key.creations.works
Site avatar

VERSION 1.0

hi, i'm key

anime + vn enjoyer

if it ain't broke, don't fix it
archium.mdx

I suck at using pacman so I wrote a C wrapper

VERT_2025-11-04 10-10-27

When you’re checking for updates, searching for a package, or installing a small tool 20 times a day, those milliseconds add up. Even fast AUR helpers like yay or paru -- great tools, written in Go and Rust respectively -- have a tiny, perceptible delay as they spin up.

It’s just enough to be annoying. And as a sysadmin wannabe and a crappy developer who loves C, I decided to stop complaining and fork archie into something I could use daily.

The Problem

My package management workflow is dead simple. I use maybe four commands 70% of the time:

  • Update everything (official repos + AUR)
  • Install a package
  • Remove a package (pacman -Rns)
  • Search for a package

I don't need a complex TUI. I don't need a million flags. I just want a wrapper that’s instant. I wanted a tool with the startup speed of a core utility like ls or grep, as silly as that might sound.

The Core Logic

I didn't want to reinvent the wheel. pacman is the source of truth, and AUR helpers are complex for a reason. My tool just needed to be a smart, fast wrapper that called the right tool for the job without needing to memorize command chains and weird args I've never heard of.

So, I 'built' archium. It's a single, tiny C binary and loosely based on archie, though not much of the original code still exists since it was a little messy.

The logic is simple: it checks its arguments and runs the correct command. The "smart" part is that it tries to guess what you want and knows what tools you prefer.

I mapped my simple commands: u for upgrade, i for install, r for remove, and s for search. I even started using more commands that I didn't before because it just felt so damn good to use.

/* A simplified look at the core execution logic */
int main(int argc, char **argv) {
    // ... find preferred package manager (pm) ...

    if (argc < 2) {
        // No args? Run the interactive shell.
        run_interactive_mode();
        return 0;
    }

    /* u - upgrade */
    if (strcmp(argv[1], "u") == 0) {
        run_command(pm, "-Syu", NULL);
    }
    /* i - install */
    else if (strcmp(argv[1], "i") == 0 && argc > 2) {
        run_command(pm, "-S", argv[2]);
    }
    /* ... and so on ... */

    return 0;
}

Making it Usable

A simple wrapper is fine, but I wanted a good user experience.

First, we added an interactive mode using the readline library. If you just run archium, you get a prompt with command history, just like a proper shell.

Second, and most importantly, I needed tab completion. This was non-negotiable. I wrote completion scripts for Bash, Fish, and Zsh. Now, when I type archium i nir... and hit [TAB], it completes to niri by feeding the output of pacman -Ssq to the shell.

A Plugin System (Losing my sanity)

This is where things got out of hand. I had other helper scripts I’d run after an update, like checking for orphaned packages or .pacnew files. I decided to build that capability directly into Archium.

I designed a C plugin API. You can write a tiny shared library (.so file), drop it in ~/.config/archium/plugins/, and Archium will load it as a new command.

The API is minimal:

/* The entire 'hello world' plugin */
#include <stdio.h>
#include <string.h>

// ArchiumError enum would go here

char *archium_plugin_get_name(void) {
  return "Hello World";
}

char *archium_plugin_get_command(void) {
  return "hello";
}

char *archium_plugin_get_description(void) {
  return "Prints a hello message";
}

ArchiumError archium_plugin_execute(const char *args, const char *package_manager) {
  printf("\033[1;32mHello from my very own plugin!\033[0m\n");
  if (args && strlen(args) > 0) {
    printf("Arguments: %s\n", args); // you can even get the args
  }
  printf("Package manager: %s\n", package_manager); // we expose this too
  return ARCHIUM_SUCCESS;
}

You just compile it: gcc -fPIC -shared -o hello.so hello.c or simply make from ~/.config/archium/plugins

Now, archium hello is a valid command. This turned a simple wrapper into a fully extensible maintenance framework. Want to update a file with your package list every time you install/remove a file? Go right ahead, buddy. You no longer have to write a bunch of random bash scripts to do that. You could write all your nerdy little desires in one plugin if you wanted. This is, obviously, a bit of a security issue since it just runs unsanitized C code. I don't care though, I think it's cool :3

The Reality Check

Is Archium for everyone? Absolutely not.

This is a massive time sink to solve a "problem" that's measured in milliseconds. Most users are, and should be, perfectly happy with yay or just a shell alias (alias u="yay -Syu").

It’s another layer of abstraction. It's written in C, which is a high barrier to entry for contributions. If it breaks, I'm the one who has to debug it.

Archium solves my specific annoyance. The binary is \<100kb. It's instant. It works exactly how my brain wants it to work. And best of all, I built it (technically gurov built it first since its a fork but who's counting).

If you're a based Arch user and are irrationally annoyed by startup lag, you can check it out on Github.

back to feed