An opinionated profile management tool for the GNU Guix package manager.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jts 1b969e7505 Add linebreak to version string. 5 months ago
src Add linebreak to version string. 5 months ago
.gitignore Initial commit 6 months ago
LICENSE Initial commit 6 months ago Port to getopt-long arg parsing. 5 months ago
guix.scm Add Guix package definition. 5 months ago


An opinionated profile management tool for the GNU Guix package manager.


guix-manage is intended to help simplify the system management of a Guix GNU/Linux system using home and system configuration files as well as profiles for package management. To use it, simply clone the repository and install the guix.scm file with Guix:

git clone
cd guix-manage
guix package -f guix.scm
guix-manage upgrade

Basic Usage

guix-manage can do two primary things: upgrade a system, and garbage collect a system, represented by the upgrade and gc subcommands, respectively. When updating, it will update everything unless it's told not to. When collecting garbage, it will delete all old generations. It does not accept a pattern because different patterns might be desired for different profiles, home, or system. If you need to delete specific generations, you'll have to do that by hand, unless you want to contribute this functionality (in which case, feel free to send me a patch).

guix-manage takes a handful of flags to modify how it operates. By default, all phase flags (the --[no-]<phase> ones) are treated as --<phase>, meaning all phases are run by default. The defaults described under Setup can be changed with the --*-dir flags. All of the flags:

  • -[q]p|--[no-]pull - whether or not to pull before on update or gc Guix itself
  • -[w]o|--[no-]home - whether or not to operate on the home config/generations
  • -[u]r|--[no-]profiles [profiles] - whether or not to operate on profiles; with arguments, only operates on/ignores the specified profiles
  • -[k]s|--[no-]system - whether or not to operate on the system config/generations
  • -c|--config-dir - where to look for manifest.scm and config.scm files; default: ~/.config/guix
  • -f|--profiles-dir - where to install profiles default: ~/.guix-profiles


There are two ways to install guix-manage. The first, Guix installation, is under Overview above. However, you can also do the installation by hand like so:

git clone
cd guix-manage
cp src/main.scm /somewhere/on/PATH/guix-manage
chmod 555 /path/to/guix-manage

Note that with this method, you may need to patch the shebang line in main.scm by hand.

guix-manage is opinionated. That means it expects a certain layout for the config directory, ~/.config/guix by default. Specifically, it expects the following structure, with exactly 0 or 1 layers of subprofiles per profile:

| - home/
    | - config.scm
| - profiles/
    | - <profile 1>/
        | - manifest.scm
    | - <profile 2>/
        | - <subprofile 1>
            | - manifest.scm
        | - <subprofile 2>
            | - manifest.scm
        | - manifest.scm
| - system/
    | - config.scm

guix-manage is opinionated. That means it's going to put profiles in a certain layout. Specifically, all profiles will be under ~/.guix-profiles. They won't be organized into subdirectories, because you shouldn't have to look at them. Each profile is simply created in that directory with the name of their manifest directory. Subprofile names are the concatenation of their parent's and their own name. For example, if you have both python/manifest.scm and python/dev/manifest.scm, both a python profile and python-dev profile will be created.

Both of these directories can be changed with flags. --config-dir sets the former directory, and --profiles-dir sets the latter. Whatever paths are provided must exist before using guix-manage; the only files it creates are profiles which it only creates using guix.

The Story

GNU Guix is a functional package manager which allows the definition of package configurations using an extension of the GNU Guile system extension language. One may install packages through the command line, as with other package managers, and roll back "generations" (a set of packages as it stands after installation or uninstallation). However, one may also define manifests of packages to install all at once. Additionally, profiles can be created to allow switching between sets of packages. Taken together, profiles and manifests allow for very nice, modular, cohesive package organization even for a single-user desktop.

But wait, there's more! The GNU/Linux distribution which uses Guix as its package manager and name extends these capabilities, allowing what is referred to as "declarative system configuration." This essentially means you can define configuration files, similar in nature to but much more powerful than manifests, which elaborate a system's locale, default packages, default services, filesystems, and more. This is such an incredibly powerful feature that it inspired an extension of that approach to home directories.

Taken all together, these features allow for a modular organization of packages, system configurations, and home directory, all using plaintext files of Guile code. This makes it possible to put an entire system's configuration under source control, giving the ability to roll-back and micromanage the system beyond even what Guix already provides.

But there's a snag. Having all these packages in all these places can make updating or garbage collecting a system a lengthy process. To upgrade a system, home, default profile, or manually-configured profile, one must run N+1 commands, where N is the number of potential upgrade targets, as Guix must update itself first.

The natural solution to this is a script. Indeed, if you look at my Guix configuration, you'll see scripts for just this purpose. They're quite simple POSIX shell scripts to call the appropriate commands in the appropriate order for how I like to update my system. But they could be more flexible. For one thing, they could allow one to specify only certain actions to take, say in the case of a failed upgrade to be resumed. And, hey, isn't Guile a scripting language? An extension language, even, for precisely the system we're managing? Why don't we rewrite these scripts more generally with more options?

And so, I present to you, guix-manage, an opinionated profile management tool for the Guix package manager.


  • write tests
  • config file at .config/guix-manage/ for setting default dirs and flags
  • implicit flag exclusivity?