GNU Guix

Increase the reproducibility of your projects with the GNU GUIX package manager.

Nicolas Fontrodona

LBMC – ENS de Lyon

Thursday, November 13, 2025

Foreword

Note

This presentation is adapted from the talk given by Romain Garbage. The material of this talk is available on numpex-pc5.gitlabpages.inria.fr.

The talk was given in an HPC context, I will focus this talk for personal use.

Reproducibility

Reproducibility demonstrates that results are not random. It is very important in science including:

  • Experimental biology
  • Bioinformatics

But reproducibility is not simple:

Baker, M. 1,500 scientists lift the lid on reproducibility. Nature 533, 452–454 (2016). https://doi-org.insb.bib.cnrs.fr/10.1038/533452a

Reproducibility crisis

Many reasons explain the result of this survey including:

  • Publication Bias
  • Inadequate Statistical Methods
  • Lack of Data Availability
  • Pressure to publish

Open science

Open Science aims to make research more efficient and productive by facilitating sharing and collaboration. As a consequence, it promotes reproducibility through transparency:

  • Open Methods
  • Open Data
  • Open Code
  • Preprints
  • Publishing in Open Access

Reproducibility in bioinformatics

In bioinformatics, even with accessible data and code it not always easy to reproduce exactly the same results. In an ideal world, we want this:

flowchart LR
    A([same Data]) --> B(Same Bioinformatics Code)
    B --> C([Same Results])

But, in reality, the following aspects can affect reproducibility:

  • Different versions of the same program
  • Dependencies hell
    • Many dependencies (long time to install them, to figure out what’s missing)
    • Conflicting dependencies
    • Availability of old dependencies
  • Different computers with different operating systems

Tools to increase reproducibility

Conda:

Advantages

  • software environment flexibility
  • software building automation

Limits

  • strong dependency on pre-installed software on the host
  • consumes disk space (multiple installation of the same package for different use)

Tools to increase reproducibility

Docker, Singularity, CharlieCloud

Advantages

  • software environment flexibility : custom content in Dockerfile or equivalent
  • automates building of an image of the software stack
  • allows to deploy the exact same software stack from machine to machine

Limits

  • no traceability / hard to recreate the same environment after time
  • consumes disk space and network bandwidth

Alternative guix

What is Guix?

  • a package manager
  • an environment manager like VirtualEnv but not limited to Python
  • a container image generation tool (like Docker, Singularity, etc.)
  • a Linux distribution (GNU Guix system)
  • a command line tool

Guix

Advantages

  • software environment flexibility
  • software building automation
  • reproducibility: same code on all the machines
  • versatility: package management, container image generation, etc.
  • useful for application deployment, but also for application development

Limits

  • less common in HPC
  • less packages available than in other package managers (like apt, pacman, …)

Package managment in Guix

From guix.gnu.org

The purpose of GNU Guix is to allow users to easily install, upgrade, and remove software packages, without having to know about their build procedures or dependencies.

For a package, guix knows about all its dependencies.

Dependency graph of python, generated with the command:

guix graph python | dot -Tpng > python_graph.png

Guix language

GNU Guix is written in the Guile/Scheme programming language.

This language can be used to write package definition or creating manifest containing a package list used to generate an environment.

Example of the hello package definition:

(define-public hello
  (package
    (name "hello")
    (version "2.10")
    (source (origin
              (method url-fetch)
              (uri (string-append "mirror://gnu/hello/hello-" version
                                  ".tar.gz"))
              (sha256
               (base32
                "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
    (build-system gnu-build-system)
    (arguments '(#:configure-flags '("--enable-silent-rules")))
    (inputs (list gawk))
    (synopsis "Hello, GNU world: An example GNU package")
    (description "Guess what GNU Hello prints!")
    (home-page "https://www.gnu.org/software/hello/")
    (license gpl3+)))

Guix installation

Guix can be installed with the installer script located on the guix.gnu.org website but it may take a while. In order to reduce the installation time you can run the following code:

# Getting the install script
wget guix.gnu.org/install.sh
chmod +x install.sh
# Using ftpmirror.gnu.org for faster downloads
sed -i 's/ftp.gnu.org/ftpmirror.gnu.org/g' install.sh
sudo ./install.sh
# Update guix with codeberg to speed up the process
guix pull --url=https://codeberg.org/guix/guix

Searching and installing packages

guix search hello
name: hello
version: 2.12.2
...

The next command can be used to install a package globally with guix.

guix install hello
# add the following line to your ~/.bashrc file or execute them directly (temporary solution) in order to use the installed packages
GUIX_PROFILE="$HOME/.guix-profile"
. "$GUIX_PROFILE/etc/profile"
# run the installed package
hello
Bonjour, le monde !
# locate where hello is installed
which hello
/var/guix/profiles/per-user/adminico/guix-profile/bin/hello
# locate the binary used
whereis hello
/gnu/store/cvds72200fhhwh1ld3ij4b77d5gk10ln-profile/bin/hello

You can search for package at https://hpc.guix.info/browse or https://packages.guix.gnu.org/

Generations and rollback

Each time guix package is invoqued, a new generation of profile containing installed packages is created.

guix install which
guix install zsh
guix package --list-generations
Génération 4    30 oct. 2025 16:03:39
 + hello    2.12.2  out /gnu/store/cs56i9digj9qg1bd383cmxc6xrfpdn9n-hello-2.12.2

Génération 5    30 oct. 2025 16:03:44
 + which    2.21    out /gnu/store/qfyqyx1v9bjhkggw7xiyna2akfcad8gs-which-2.21

Génération 6    30 oct. 2025 16:03:53   (actuelle)
 + zsh  5.9 out /gnu/store/jv1ylg1cv1i73az182i7gz9gvsp16smf-zsh-5.9
guix package --roll-back
passé de la génération 6 à 5
guix package --roll-back
passé de la génération 5 à 4
guix package --list-installed
hello   2.12.2  out /gnu/store/cs56i9digj9qg1bd383cmxc6xrfpdn9n-hello-2.12.2
guix package --switch-generation=6
passé de la génération 4 à 6

Uninstalling packages

# uninstall the hello package
guix remove hello # `guix remove hello which zsh` to remove everything
Le paquet suivant sera supprimé :
   hello 2.12.2
hello
zsh: command not found: hello
/gnu/store/cvds72200fhhwh1ld3ij4b77d5gk10ln-profile/bin/hello
Bonjour, le monde !

To permanently remove the package and free up disk space, you can run guix gc. It will remove unused packages from /gnu/store.

Unused packages

An unused package is a package that is not present in any user profile (including old generation profiles).

guix package --delete-generations # delete all previous generations except the current one
guix gc
# /gnu/store/cvds72200fhhwh1ld3ij4b77d5gk10ln-profile/bin/hello is not present anymore

Environments with guix shell

The guix shell command allows users to create single use isolated environments with specific packages installed without changing your profile.

Let’s create an environment with GCC and openmpi

guix shell gcc-toolchain openmpi # install the packages needed and start a new shell
gcc --version
mpirun --version
echo $GUIX_ENVIRONMENT
/gnu/store/pgna460sq79n5cq4z67b1q77883ajrjg-profile
echo $PATH
/var/guix/profiles/per-user/adminico/guix-profile/bin:/gnu/store/pgna460sq79n5cq4z67b1q77883ajrjg-profile/bin ...
exit

Creating a containerized environment

To create the same environment as above but in a completely isolated way, you can use the -C option. Only the current working directory and the installed packages will be accessible in the containerized environment.

guix shell -C gcc-toolchain openmpi # start a containerized environment

Option container

The -C / --container option requires user namespaces kernel feature activation

Important

With the above command, ls and which will not be accessible. You can add coreutils and which package to the previous command in order to be able to use ls and which .

guix shell -C gcc-toolchain openmpi coreutils which
echo $PATH
/gnu/store/qk4f12k4rzycpm16v9a1v5k314pkjaiy-profile/bin:/gnu/store/qk4f12k4rzycpm16v9a1v5k314pkjaiy-profile/sbin

Option pure

The --pure option allows to reset environment variables when building the new environment. The PATH variable only contains packages entries defined in the guix shell command.

Environments and manifest

Let’s say we want to create an environment with:

  • python
  • poetry (uv is not up to date and does not work)
  • r
  • tidyverse

We can run the following command:

# The first time you run this command, it will take a while to download the packages
guix shell python poetry r r-tidyverse --with-latest=r-rvest
# create a manifest file with the packages you need to create your environment:
guix shell python poetry r r-tidyverse --with-latest=r-rvest --export-manifest > manifest.scm
# Run guix shell using the manifest file (equivalent to the first command):
guix shell -m manifest.scm
cat manifest.scm
(use-modules (guix transformations))

(define transform1
  (options->transformation
    '((with-latest . "r-rvest"))))

(packages->manifest
  (list (transform1 (specification->package "python"))
        (transform1 (specification->package "poetry"))
        (transform1 (specification->package "r"))
        (transform1
          (specification->package "r-tidyverse"))))

Updating Guix

The guix pull command downloads the latest version of Guix and updates the package definition.

It’s similar to sudo apt update in Debian or Ubuntu.

Installed packages with the guix install command can be updated with:

guix package -u

It’s similar to sudo apt upgrade in Debian or Ubuntu.

Tip

The guix shell environments always use the current packages definition and thus, they don’t need to be updated.

Adding channels

Channels:

  • Are git repositories that contain package definitions and more.
  • Are defined in ~/.config/guix/channels.scm

Each user can use a specific set of channels.

guix pull must be run after a change in channels to pull their content.

Guix describe

To get the channels currently available to guix and their current commit, you can run:

guix describe
Génération 3    22 oct. 2025 13:35:43   (actuelle)
  guix-past c3bc94e
    URL du dépôt : https://codeberg.org/guix-science/guix-past.git
    branche : master
    commit : c3bc94ee752ec545e39c1b8a29f739405767b51c
  guix 5440063
    URL du dépôt : https://codeberg.org/guix/guix.git
    commit : 54400639a4cfb8358b27b1d2563c21c70c6fcf49

You can save those definition in a file in order to reuse them later with:

guix describe -f channels > channels.scm

Tip

By using sharing this file along with a manifest file you can make sure that everyone will use exactly the same environment.

guix pull -C channels.scm # To update guix in order to use the exact same guix version and package definition
guix shell -m manifest.scm

Guix time-maching

The guix time-machine command allows to run a guix command with a specific revision/commit of Guix and/or different channels without modifying the default environment (e.g Guix version and channels).

For example to deploy the same environment in a reproducible way you can run:

guix time-machine -C channels.scm -- shell -m manifest.scm

Note

guix time-machine can also be used to activate different channels without changing the current user channels.

guix search quantum-espresso
# nothing appears
# same command but using a channel containing the package quantum-espresso
guix time-machine -C channels.scm -- search quantum-espresso

BONUS: Guix limits and Nix

Currently, there is “only” about 30000 packages available in guix default channel. This number reach about 55000 packages when including the 7 channels defined in https://hpc.guix.info/channels website. It’s a good amount for many bioinformatics projects but some may require specific packages not present in guix.

One of your option is to create a guix package definition.

Tip

You can use the guix import [source] [package] command in order to import the metadata of a package defined in different source like pypi, cran, gnu, crate in order to help you create a package definition for installing a specific package not yet available in guix.

You can also use package transformation options like --with-latest in the guix shell command in order to build a more recent version of a package.

Important

But, despite that, it can be quite tedious and take a long time to create a working package definition from scratch, especially when your not an expert in Guile/Scheme

BONUS: Guix limits and Nix

If you wish to use a package that is not yet available in Guix, Nix can be a good alternative:

Advantages

  • Nix has a bigger community
  • it contains more than 120k packages (see this website)
  • packages are often more up-to-date than in Guix (expect for R packages)

Nix is similar to Guix in multiple ways:

  • A part of Guix is a fork of Nix
  • Nix is a package manager
  • Nix is an environment manager
  • Nix is an Linux distribution (NixOS)
  • Nix is a language

Limitations

  • Nix is a specific language
  • Nix doesn’t have --container option like in guix

BONUS: Nix environment with flakes

Nix flakes is an experimental feature improving reproducibility through the usage of a lock file (containing version pinned dependencies of an environment).

To enable flakes, you need to add the following line to your ~/.config/nix/nix.conf file:

experimental-features = nix-command flakes

Then you can write a flake.nix file to define your environment:

{
  description = "My awesome environment";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
  };

 outputs = { self, nixpkgs }:
    let
      pkgs = nixpkgs.legacyPackages."x86_64-linux";
    in
    {
      devShells."x86_64-linux".default = pkgs.mkShell {
        packages = [pkgs.python314 pkgs.uv pkgs.R pkgs.rPackages.tidyverse ];
      };
    };
}

You can search for packages name here: https://search.nixos.org/packages?channel=unstable&

BONUS: Nix environment with flakes

In a folder containing a flake.nix file, you can run

nix develop --command $SHELL # The --command $SHELL ensure that you keep your default shell

This will create a flake.lock file in your repository pinning the version of the dependencies used

BONUS: Devbox

Some tools are dedicated to ease the usage of Nix. One of them is devbox.

With devbox, you can easily manage your developement environment and share it with other. You can also define custom flakes files in order to build specific nix packages and use them in devbox.

devbox init # to initialize a project (create a devbox.json and a devbox.lock files)
devbox search # to search for a nix package
devbox add [package] # to add a package to your environment
devbox rm [package] # to remove a package from your environment
devbox shell # to enter in your environment
devbox shell --pure # to enter in your environment with a pure shell (with a clean PATH variables)

Conclusion

Guix:

  • Is a package manager
    • guix install package to install a package
    • guix remove package to remove a package
    • guix gc to free disk space by removing unused packages
  • Is a great tool to create reproducible environments and share them
    • guix shell package1 package2 to create an environment
    • guix shell package1 package2 --export-manifest > manifest.scm && guix describe -f channels > channels.scm to create a manifest and a channel file in order to share a reproducible environment
    • guix time-machine -C channels.scm -- shell -m manifest.scm to recreate an environment shared by others
  • Can lack some packages, in this case Nix/devbox can be an alternative