Benoit J - My mostly tech blog

Guix home configuration - part 1 - Packages


The most important part of my Nix configuration: nix home manager.

From packages installed, services enabled, configuration copied or generated, home manager is where the Linux “customization” happens.

Nix flakes alternative

Lets make this simple, my primary flake is my dotfile configuration.

No matter the setup, both Nix and Guix rely on the source control to make sure the packages are reproducible. When you pull on sync your channels, Guix (or Nix) “pull” changes to a local copy of the repository.

In functional expression, a flake derivation would look like this: f(pinnedInputs, configuration) = configDerivation where pinnedInputs are the channel + commit hash for each flake (channel) specified and stored in git.

This makes the configuration flake, a function of it’s input. It’s reproducible, there are no external dependencies.

In Guix, the pinnedInputs exists, but are external and kind of invisible to the user. They represent your last “pull” command, nothing more. It’s place sensitive and not captured anywhere but on your local machine.

What it means in practice?

Without this critical information, re-installing the configuration will produce different results, unless Guix (or Nix) did not change since last time you did it.

For example, last time I migrated to Guix, using my previous migration’s configuration, I could not get chezmoi dotfile manager to work. It failed to build between the time I left Guix and the time I re-installed Guix. I had spend time figuring out when the build started to fail, and wasted time getting my system up to date.

The solution for this is to store both the channels used by the configuration as well as the git hash versions of each channels. When they are in your repository, you have a lot more chance to get a working system, especially after some time. It also make it super easy to upgrade one channel while keeping an older version of another one by just undoing your changes using git.

When you are a coder, this is super natural to do. Many of the development tools actually have similar mechanism (like npm’s package.lock).

how do we achieve that with Guix?

Guix does not have an off the shelf pinning system, but has some commands to support similar workflow: describe and time-machine.

On any Guix system, if you run guix describe --format channels, you get the same info as your channel file, but with the specific git hash from the latest guix pull. We could store this output into a file in our configuration git repo for later reference.

The 2nd useful command is guix time-machine. It allows you to run a Guix command for a specific version. There are many ways to specify the version, one of which is a channels file. We can use the output of guix describe to run guix pull at a specific version using guix time-machine.

The is the closest we can get from Nix flakes.

The main limitation is that Nix flakes tracks inputs of inputs, while guix describe/time-machine will only track your immediate channels specifications.

This is the same mechanism that RDE uses (look at their setup here).

Software packages

Here is an inventory of all the software I use, except for anything related to nix home-manager (programs and services).

I’m been using whereiseveryone’s toy search engine. It index Guix main channel, but also many other 3rd party channels. The search engine is not just more complete, it’s also much faster than Guix packages web search engine.

In my case, most will come from Guix’s channel, some from NonGuix, and the rest from my own channel.

Note: before installing any software from 3rd party channels, it’s always advised to inspect the Guix package code, and even better, inspect and replicate some of them into your own channel. You should not leave security to luck. Since I only have couple of packages in unknown 3rd party channels, I’ll inspire myself and update my own channel.


Shell and core tools

nix guix ([channel#]<package>[:output]) comment
babashka bin-guix#babashka issue is graalvm not in Guix due to reproducibility
bat =
bash-completion =
coreutils =
dosfstools = dos partitioning/formatting tools
lesspipe =
nix-bash-completions missing, abandon I dont really need it
starship th#starship-bin This could go in Guix, but really a lot of dependencies


nix guix ([channel#]<package>[:output]) comment
bluez =
bluez-alsa =
bind bind:utils I use the lookup tools
curl =
openssl =
rsync =
sshfs =
surfraw =
tig abandon I dont use this anymore
wget =

File management and processing

nix guix ([channel#]<package>[:output]) comment
(aspellWithDicts (dicts: with dicts; [ en en-computers en-science fr])) aspell, aspell-dict-en, aspell-dict-fr Note en-computers and en-science in kbg
kbg#aspell-dict-en-computers, kbg#aspell-dict-en-science Note2: aspellWithDicts equivalent?
atool abandon file archive manager I dont use
beancount =
bsdgames bsd-games
cowsay =
dateutils abandon I dont use this
dos2unix =
diffutils = diff, cmp, diff3
fd = find replacement
figlet = banner tools-extra
findutils = find, locate commands
fzf =
gawk =
gnuplot =
gzip =
highlight =
jet missing, nixpkgs like jq, but include transit and edn
jq =
ledger =
mediainfo =
p7zip =
pandoc =
pbzip2 = # multi core replacement for bzip2/bunzip2
recutils =
ripgrep =
tree =
texlive.combined.scheme-full texlive
unrar -> p7zip
unzip =
wordnet =
zip =

Process management and monitoring

nix guix comment
acpi =
htop =
lsof =
progress =
pv = pipe progress monitor
strace =
sysstat =

Media tools

nix guix comment
alsa-plugins =
alsa-tools missing, abandon I’m not sure I actually use this
alsa-utils =
apulse missing, abandon not found but don’t use
ffmpeg =
gst_all_1.gst-plugins-base gst-plugins-base
gst_all_1.gst-plugins-good gst-plugins-good
gst_all_1.gst-plugins-bad gst-plugins-bad
gst_all_1.gst-plugins-ugly gst-plugins-ugly
gst_all_1.gstreamer gstreamer
imagemagick =
mpv =
pulsemixer =
pamixer =
sox =
vorbis-tools =


nix guix comment
keychain = great tool to share ssh/gpg agents within a session
gnupg =
pass password-store
pinentry =

Containers, images and virtualization, and deployment

nix guix comment
deploy-rs missing, abandon I used this for some of my servers. I have a diff solution now
docker-compose docker, docker-cli, docker-compose Unclear if compose is needed as it’s supported in cli on new versions
vagrant missing, nixpkgs I would want to use that to provision my work VMs

Programming tools

nix guix comment
ansible =
autoconf =
automake =
binutils = ld and similar tools
black python-black python code formatter
cargo =
clj-kondo nonguix#clj-kondo clojure linter
clojure clojure, clojure-tools this is new. was not in Guix if I recall
clojure-lsp missing, nixpkgs could not find. self package?
cmake =
editorconfig-core-c =
gcc =
gh ffab#github-cli
ghc =
gitFull git:out,send-email,gui
git-annex =
git-doc N/A
git-extras missing, wait lots of cool features. Maybe there is an emacs similar package. some are covered by magit
git-hub -> github-cli
git-stree abandon I use magit
gitstats magit-stats
gnumake make
go =
gopls = go language server
graphviz =
html-tidy missing, nixpkgs
jdk17 openjdk 21 is also available
jetbrains.idea-ultimate small-guix#idea-ultimate
leiningen nonguix#leiningen
libtool =
maven =
google-java-format missing, nixpkgs cli java formatter
mdl missing, nixpkgs markdown linter
mr myrepos
nodejs node latest lts available (18)
nodePackages.stylelint -> node-eslint
nodePackages.js-beautify missing, -> npm prettier replace with prettier from npm?
nixfmt from nix package mgr
plantuml =
pipenv missing, wait
pyenv missing, wait
python3 python
python-lsp-server =
python beautifulsoup4 python-beautifulsoup4
python flake8 python-flake8
python isort python-isort
python lxml python-lxml
python mypy python-mypy
python nose python-nose
python pillow python-pillow
python pyflakes python-pyflakes
python pylint python-pylint
python pynacl python-pynacl
python pytest python-pytest
python pyright missing, abandon some extra linting, not critical
python pypdf2 python-pypdf2
python terraform =
python tldextract python-tldextract
proselint python-proselint
ruby =
rustc rust
sbcl =
shellcheck =
shfmt missing, nixpkgs
sqlite =
vscode-fhs missing, wait it’s a wrapper that allows to install vscode plugin normally
is vscodium doing the same?

Tools perso

Tools I use only on my personal laptop

nix guix ([channel#]<package>[:output]) comment
borgbackup borg
borgmatic =
bitwarden -> rbw
bitwarden-cli -> rbw
hugo rosental#hugo-bin
rbw = bitwarden client
rofi-rbw missing, nixpkgs rofi frontend. easy to package
syncthing =
transmission =
yt-dlp =
yubikey-manager python-yubikey-manager
beancount =
beancount-language-server missing, nixpkgs
fava missing, nixpkgs
hledger =
chezmoi abandon
profanity =
kicad =
qmk missing, git clone I may be able to clone qmk instead
abcde =
beets =
cdrdao =
cdparanoia =
cddiscid missing, nixpkgs
chromaprint =
dr14_tmeter missing, nixpkgs
flac =
fluidsynth =
mopidy missing, wait
mopidy-local missing, wait
#mopidy-spotify missing, wait
mopidy-somafm missing, wait
mopidy-mpd missing, wait
mopidy-iris missing, wait
#mopidy-internetarchive missing, wait
mpc_cli mpd-mpc
mpd =
ncmpcpp =
ncspot missing, nixpkgs
opusTools opus-tools
python39Packages.pyacoustid missing, wait
python39Packages.requests python-requests
rubberband =
sox =
spotifyd missing, wait
spotify-tui missing, wait
twolame =
wavegain missing, wait

When missing, i’ll just use the nix package instead until I do something else about it.

Tools work

nix guix ([channel#]<package>[:output]) comment
awscli2 awscli
azure-cli missing, nixpkgs


nix guix ([channel#]<package>[:output]) comment
alacritty =
arandr =
autorandr =
brightnessctl =
cantarell-fonts font-abattis-cantarell
dunst =
fontconfig =
dejavu_fonts font-dejavu
dwm mychannel#bmj-dwm
feh =
firefox nonguix#firefox
gimp =
libnotify =
libreoffice =
light =
kdiff3 missing, abandon use emerge, or other diff tools
maim =
mate.mate-polkit mate-polkit
mpv mpv
mupdf -> zathura
nerdfonts CascadiaCode mychannel
nerdfonts FiraCode mychannel
nerdfonts Hack mychannel
picom =
projectm missing, abandon
qutebrowser nixpkgs guix has a build that don’t work for me
rofi =
scrot -> maim
st mychannel#bmj-st
sxiv =
tesseract4 tesseract, tesseract-* I dont need this now
widevine-cdm missing, nixpkgs needed for qute
wmctrl =
xclip =
xdg-utils =
xdg-user-dirs =
xdotool =
xdragon dragon-drop
xlockmore =
xorg.setxkbmap xkbset?
xorg.xev xev
xorg.xinput xinput
xorg.xrandr xrandr
xorg.xrdb xrdb
xorg.xset xset
xsel xsel
zathura zathura, zathura-*

what’s next?

My program.* and services.* nix configuration -> service-types mapping.