flowchart LR
A([same Data]) --> B(Same Bioinformatics Code)
B --> C([Same Results])
Increase the reproducibility of your projects with the GNU GUIX package manager.
LBMC – ENS de Lyon
Thursday, November 13, 2025
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 demonstrates that results are not random. It is very important in science including:
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
Many reasons explain the result of this survey including:
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:
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:
Conda:
Advantages
Limits
Docker, Singularity, CharlieCloud
Advantages
Limits
What is Guix?
Advantages
Limits
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.
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 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
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
helloYou can search for package at https://hpc.guix.info/browse or https://packages.guix.gnu.org/
Each time guix package is invoqued, a new generation of profile containing installed packages is created.
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
# uninstall the hello package
guix remove hello # `guix remove hello which zsh` to remove everythingTo 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
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
/var/guix/profiles/per-user/adminico/guix-profile/bin:/gnu/store/pgna460sq79n5cq4z67b1q77883ajrjg-profile/bin ...
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.
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 .
/gnu/store/qk4f12k4rzycpm16v9a1v5k314pkjaiy-profile/bin:/gnu/store/qk4f12k4rzycpm16v9a1v5k314pkjaiy-profile/sbinOption 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.
Let’s say we want to create an environment with:
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(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"))))
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:
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.
Channels:
~/.config/guix/channels.scmEach user can use a specific set of channels.
guix pull must be run after a change in channels to pull their content.
To get the channels currently available to guix and their current commit, you can run:
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 : 54400639a4cfb8358b27b1d2563c21c70c6fcf49You can save those definition in a file in order to reuse them later with:
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:
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
If you wish to use a package that is not yet available in Guix, Nix can be a good alternative:
Advantages
Nix is similar to Guix in multiple ways:
Limitations
--container option like in guixNix 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:
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&
In a folder containing a flake.nix file, you can run
This will create a flake.lock file in your repository pinning the version of the dependencies used
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)
Guix:
guix install package to install a packageguix remove package to remove a packageguix gc to free disk space by removing unused packagesguix shell package1 package2 to create an environmentguix 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 environmentguix time-machine -C channels.scm -- shell -m manifest.scm to recreate an environment shared by others