Homebrew m’accompagne depuis mes débuts sur macOS. brew install, brew search, brew upgrade, et tout fonctionne. Alors pourquoi changer ? Parce que ma machine est devenue le seul élément de mon environnement que je ne décris pas dans du code.
Mon infrastructure est déclarée dans Terraform, mes rôles Ansible sont versionnés, mes déploiements Kubernetes sont des manifests. Mais mon poste de travail, lui, reste le résultat d’une accumulation de brew install dont je n’ai aucune trace fiable. Nix vient corriger ce problème : la liste de mes paquets devient un fichier texte, versionnable, reproductible sur n’importe quel Mac en une commande.
Cet article est à la fois un retour d’expérience et une procédure : comprendre ce qu’est Nix, récupérer l’inventaire de vos paquets Homebrew, installer Nix sur macOS avec home-manager, puis désinstaller brew.
Nix, nixpkgs, NixOS : trois choses différentes pour une même philosophie#
Les trois termes sont souvent confondus, alors clarifions.
Nix
est un gestionnaire de paquets, au même titre que apt ou Homebrew, mais avec une philosophie radicalement différente : chaque paquet est construit de manière isolée et stocké dans /nix/store sous un chemin contenant le hash de toutes ses dépendances. Deux versions d’un même logiciel cohabitent sans conflit. Nix fonctionne sur Linux et macOS sur les architectures x86_64 (AMD64) et aarch64 (ARM64).
nixpkgs est le dépôt de paquets utilisé par Nix. Avec plus de 140 000 paquets, c’est le dépôt le plus fourni de l’écosystème libre, devant l’AUR d’Arch Linux et loin devant les quelque 7 000 formules de Homebrew. Il suit un cycle de versions stables semestriel : la version stable actuelle est la 26.05, sortie en mai 2026.
NixOS est une distribution Linux entièrement construite autour de Nix : le système complet (noyau, services, utilisateurs, réseau) est décrit dans un fichier de configuration. C’est l’aboutissement logique de la démarche, mais ce n’est pas le sujet ici : sur un Mac, on utilise Nix comme gestionnaire de paquets par-dessus macOS, pas NixOS.
La finalité de tout cela est de pouvoir déclarer ses paquets dans un fichier, et de les installer de façon reproductible sur n’importe quel système.
Ce que Nix implique vraiment#
Avant de vous lancer, soyons honnêtes : Nix est compliqué. Pas l’installation ni l’usage quotidien, mais le modèle mental et le langage.
Nix ne respecte pas le FHS. Le Filesystem Hierarchy Standard (/usr/bin, /usr/lib, /etc…) est ignoré. Tout vit dans /nix/store/<hash>-<nom>-<version>/, et des liens symboliques exposent les binaires dans votre profil utilisateur. Conséquence directe : un binaire téléchargé qui s’attend à trouver ses bibliothèques dans /usr/lib ne fonctionnera pas dans un environnement Nix pur. Sur macOS c’est moins douloureux que sur Linux (le système de base reste intact), mais gardez-le en tête.
Le langage Nix a une courbe d’apprentissage réelle. C’est un langage fonctionnel, paresseux, avec une syntaxe qui déroute. Pour installer une liste de paquets, vous n’en verrez presque rien. Pour packager vos propres logiciels ou surcharger un paquet existant, comptez plusieurs soirées de documentation.
La documentation est fragmentée. Entre le manuel officiel, le wiki communautaire, les blogs et les dépôts d’exemples, trouver la « bonne » façon de faire demande du tri. L’écosystème évolue vite et beaucoup de tutoriels sont obsolètes.
Ce que vous gagnez en échange :
- Un environnement déclaratif : votre liste de paquets est un fichier, versionnable dans Git
- Des rollbacks natifs : chaque changement crée une génération, retour arrière en une commande
- La reproductibilité : le même fichier produit le même environnement sur un autre Mac ou un serveur Linux
- Des environnements de développement isolés par projet avec
nix-shell, sans polluer le système
| Quand Nix est-il pertinent ? | Quand brew suffit |
|---|---|
| vous gérez plusieurs machines | vous avez un seul Mac |
| vous voulez reconstruire votre poste rapidement | une dizaine de paquets |
| vous pratiquez déjà l’infrastructure as code | aucune envie d’apprendre un langage fonctionnel pour installer wget |
| vous avez besoin d’environnements de développement reproductibles |
Récupérer l’inventaire Homebrew#
Première étape, avant de toucher à quoi que ce soit : sauvegardez la liste de vos paquets.
# Paquets installés explicitement (sans les dépendances)
brew leaves > ~/brew-formulae.txt
# Applications graphiques installées via cask
brew list --cask > ~/brew-casks.txt
# Sauvegarde complète au format Brewfile, par sécurité
brew bundle dump --file=~/Brewfilebrew leaves est la commande importante : elle ne liste que les paquets que vous avez demandés, pas les dépendances tirées automatiquement. C’est cette liste que vous allez traduire en paquets Nix. Le Brewfile sert de filet de sécurité : si la migration tourne mal, brew bundle install restaure tout.
Pour chaque paquet de la liste, vérifiez son équivalent dans nixpkgs sur search.nixos.org
. Dans l’immense majorité des cas, le nom est identique (go, hugo, jq, kubectl). Quelques pièges classiques : awscli devient awscli2, certains paquets sont préfixés ou regroupés différemment.
Installer Nix sur macOS : deux installeurs#
Depuis janvier 2026, le paysage a changé. L’installeur de Determinate Systems, longtemps recommandé par la communauté, n’installe plus que Determinate Nix, leur distribution downstream avec configuration verrouillée et fonctionnalités maison. En réponse, le groupe de travail de la communauté NixOS a forké cet installeur pour proposer un équivalent qui installe le Nix upstream.
| Installeur communautaire (NixOS) | Determinate Nix | |
|---|---|---|
| Nix installé | Upstream (officiel) | Distribution downstream |
| Configuration | Libre (/etc/nix/nix.conf) | Verrouillée, surcharge via nix.custom.conf |
| Flakes | Optionnels (--enable-flakes) | Activés et imposés |
| Désinstallation | nix-installer uninstall | nix-installer uninstall |
| Cible | Usage communautaire standard | Entreprises, support commercial |
Comme je n’utilise pas les flakes et que je veux rester sur le Nix officiel, je choisis l’installeur communautaire :
curl -sSfL https://artifacts.nixos.org/nix-installer | sh -s -- installL’installeur crée un volume APFS dédié pour /nix, configure le démon et les utilisateurs de build. Il survit aux mises à jour majeures de macOS, ce qui était le point faible historique de l’installation Nix sur Mac. Voici le retour de la commande sur ma machine :
$ curl -sSfL https://artifacts.nixos.org/nix-installer | sh -s -- install
info: downloading installer
INFO nix-installer v2.34.6
`nix-installer` needs to run as `root`, attempting to escalate now via `sudo`...
Password:
INFO nix-installer v2.34.6
Welcome to the Nix installer!
Flakes are an experimental feature, but widely used in the community.
You can change this later in `/etc/nix/nix.conf`.
Enable flakes?
Proceed? ([Y]es/[n]o): n
Note: the experimental nix-command feature has been enabled.
Commands starting with `nix ` (e.g. `nix build`) are subject to interface changes.
Nix install plan (v2.34.6)
Planner: macos (with default settings)
Planned actions:
* Create an APFS volume `Nix Store` for Nix on `disk3` and add it to `/etc/fstab` mounting on `/nix`
* Unpack embedded Nix 2.34.6 to `/nix/temp-install-dir`
* Create a directory tree in `/nix`
* Synchronize /nix/var ownership
* Move the downloaded Nix into `/nix`
* Synchronize /nix/store ownership
* Create build users (UID 351-382) and group (GID 350)
* Configure Time Machine exclusions
* Setup the default Nix profile
* Place the Nix configuration in `/etc/nix/nix.conf`
* Configure the shell profiles
* Configuring zsh to support using Nix in non-interactive shells
* Create a `launchctl` plist to put Nix into your PATH
* Configure upstream Nix daemon service
* Remove directory `/nix/temp-install-dir`
Proceed? ([Y]es/[n]o/[e]xplain): y
INFO Step: Create an APFS volume `Nix Store` for Nix on `disk3` and add it to `/etc/fstab` mounting on `/nix`
INFO Step: Provision Nix
INFO Step: Create build users (UID 351-382) and group (GID 350)
INFO Step: Configure Time Machine exclusions
INFO Step: Configure Nix
INFO Step: Configuring zsh to support using Nix in non-interactive shells
INFO Step: Create a `launchctl` plist to put Nix into your PATH
INFO Step: Configure upstream Nix daemon service
INFO Step: Remove directory `/nix/temp-install-dir`
INFO Waiting up to 10s for Nix daemon socket
INFO Running self test for shell sh
INFO Running self test for shell bash
INFO Running self test for shell zsh
Nix was installed successfully!
To get started using Nix, open a new shell or run `. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh`Ouvrez un nouveau terminal, lancez la commande suivante . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh (ou ouvrez un nouveau terminal comme suggéré) et vérifiez que la commande nix est disponible : nix --version.
Configurer home-manager#
Nix seul permet d’installer des paquets impérativement (nix-env -iA), mais ce serait passer à côté de l’intérêt. home-manager apporte la couche déclarative : un fichier home.nix décrit vos paquets et vos dotfiles, une commande applique le tout.
Ajoutez les canaux nixpkgs stable pour Darwin et home-manager, en versions alignées :
# Canal nixpkgs stable pour macOS
nix-channel --add https://nixos.org/channels/nixpkgs-26.05-darwin nixpkgs
# Canal home-manager correspondant
nix-channel --add https://github.com/nix-community/home-manager/archive/release-26.05.tar.gz home-manager
nix-channel --updateL’alignement des versions est obligatoire : home-manager release-26.05 avec nixpkgs 26.05. Un décalage produit des avertissements, voire des erreurs. Sur ma machine, voici le résultat :
nix-channel --add https://nixos.org/channels/nixpkgs-26.05-darwin nixpkgs
nix-channel --add https://github.com/nix-community/home-manager/archive/release-26.05.tar.gz home-manager
nix-channel --update
this derivation will be built:
/nix/store/71286qwagzrzkl1pj75qsmqwjadlbi7c-home-manager-26.05.tar.gz.drv
building '/nix/store/71286qwagzrzkl1pj75qsmqwjadlbi7c-home-manager-26.05.tar.gz.drv'...
unpacking 2 channels...Installez home-manager :
# la commande suivante génère le fichier "~/.config/home-manager/home.nix",
# qui remplacera votre historique de "brew install".
# la commande paraît "bizarre" avec le '<home-manager>' mais c'est la syntaxe correcte de nix
nix-shell '<home-manager>' -A installSelon la puissance de votre machine, cette commande peut prendre quelques minutes. Voici le résultat pour ma part :
...
Starting Home Manager activation
Activating checkAppManagementPermission
Activating checkFilesChanged
Activating checkLinkTargets
Activating writeBoundary
Activating installPackages
installing 'home-manager-path'
building '/nix/store/n1hchpca0vhivdqjpj5xjl20fsc7m94p-user-environment.drv'...
Activating linkGeneration
Creating home file links in /Users/jh
Activating copyApps
setting up ~/Applications/Home Manager Apps...
Activating onFilesChange
Activating setupLaunchAgents
this derivation will be built:
/nix/store/9w9kjz97kirav8g4vxcgwq42mv7x59kf-hm-news.json.drv
building '/nix/store/9w9kjz97kirav8g4vxcgwq42mv7x59kf-hm-news.json.drv'...
All done! The home-manager tool should now be installed and you can edit
/Users/jh/.config/home-manager/home.nix
to configure Home Manager. Run 'man home-configuration.nix' to
see all available options.Déclarer ses paquets#
Voici mon home.nix, à adapter avec votre propre liste issue de brew leaves :
{ config, pkgs, ... }:
{
home.username = "jh";
home.homeDirectory = "/Users/jh";
# Version d'état : ne pas modifier après l'installation initiale
home.stateVersion = "26.05";
# Liste des paquets, équivalent déclaratif de brew leaves
home.packages = with pkgs; [
go
hugo
kubectl
];
# home-manager se gère lui-même
programs.home-manager.enable = true;
}Appliquez la configuration :
home-manager switchChaque switch crée une nouvelle génération. En cas de problème :
# Lister les générations
home-manager generations
# Revenir à la génération précédente
home-manager switch --rollbackC’est ici que la différence avec brew devient concrète : ajouter un paquet, c’est ajouter une ligne dans un fichier et relancer switch. Le fichier part dans Git. Un nouveau Mac se configure en trois commandes : installeur, deux canaux, home-manager switch.
La limite : certaines applications graphiques#
Soyons clairs sur le point faible. Les casks Homebrew (VLC, Zen, OrbStack…) n’ont pas tous un équivalent dans nixpkgs sur macOS. Certaines applications graphiques y sont packagées, mais l’intégration (mises à jour automatiques, signature, emplacement dans /Applications) reste inférieure à ce que font les casks. Pour VLC, le paquet est construit exclusivement pour les systèmes linux :
error: Refusing to evaluate package 'vlc-3.0.23-2' in /nix/store/3wq8jm2hlpwd6xnwyrbj55sgh3cbxq0a-nixpkgs-26.05-darwin/nixpkgs/pkgs/by-name/vl/vlc/package.nix:315 because it is not available on the requested hostPlatform:
hostPlatform.system = "aarch64-darwin"
package.meta.platforms = [
"aarch64-linux"
"arc-linux"
"armv5tel-linux"
"armv6l-linux"
"armv7a-linux"
"armv7l-linux"
"i686-linux"
"loongarch64-linux"
"m68k-linux"
"sh4-linux"
"microblaze-linux"
"microblazeel-linux"
"mips-linux"
"mips64-linux"
"mips64el-linux"
"mipsel-linux"
"powerpc-linux"
"powerpc64-linux"
"powerpc64le-linux"
"riscv32-linux"
"riscv64-linux"
"s390-linux"
"s390x-linux"
"x86_64-linux"
]Quand ce genre d’erreur apparaît, il y a trois options pragmatiques :
- Télécharger les quelques applications graphiques directement depuis leur site (elles s’auto-mettent à jour pour la plupart)
- Garder un brew minimal uniquement pour les casks, et Nix pour tout le CLI
- Utiliser les paquets GUI de nixpkgs quand ils existent et accepter les compromis
J’ai choisi la première option : mes applications graphiques se comptent sur les doigts d’une main et se mettent à jour seules. Tout le reste, c’est-à-dire l’essentiel de mon outillage, passe par Nix.
Les licences “unfree”#
Certaines applications ont une licence non libre : elles sont bien présentes dans nixpkgs, mais Nix refuse de les évaluer par défaut. C’est le cas de claude-code, l’agent de codage en ligne de commande développé par Anthropic. L’erreur suivante apparaîtra pour les paquets concernés : error: Refusing to evaluate package 'claude-code-2.1.187' in /nix/store/3wq8jm2hlpwd6xnwyrbj55sgh3cbxq0a-nixpkgs-26.05-darwin/nixpkgs/pkgs/by-name/cl/claude-code/package.nix:92 because it has an unfree license (‘unfree’)
Pour installer ces applications, il est nécessaire d’ajouter cette ligne dans votre fichier de configuration de Nix, au début du fichier (pas de convention officielle) :
{ config, pkgs, ... }:
{
nixpkgs.config.allowUnfree = true;
# ...
}Migration des applications de brew vers nix#
Avant de se lancer corps et âme dans la migration, il est important de tester quelques applications vers nix pour vérifier que tout fonctionne comme attendu. Selon la liste des applications que vous avez générée précédemment, vous pouvez commencer par migrer les applications les moins utilisées ou les moins sensibles. Pour ma part, je vais commencer par migrer go, hugo et kubectl, ceux déjà déclarés plus haut dans mon home.nix. Je désinstalle les versions installées par brew et je les installe via home-manager.
# Désinstaller les versions installées par brew
$ brew uninstall go hugo kubectl
Error: Refusing to uninstall /opt/homebrew/Cellar/go/1.26.4
because it is required by golangci-lint and gosec, which are currently installed.
You can override this and force removal with:
brew uninstall --ignore-dependencies go hugo kubectl
$ brew uninstall golangci-lint gosec go hugo kubectl
Uninstalling /opt/homebrew/Cellar/golangci-lint/2.12.2... (11 files, 43.3MB)
Uninstalling /opt/homebrew/Cellar/gosec/2.27.1... (6 files, 40.4MB)
Uninstalling /opt/homebrew/Cellar/go/1.26.4... (14,961 files, 228.6MB)
Uninstalling /opt/homebrew/Cellar/hugo/0.163.3... (54 files, 91MB)
Uninstalling /opt/homebrew/Cellar/kubernetes-cli/1.36.2... (261 files, 62.5MB)
# Ajouter les paquets à home-manager
$ vim /Users/jh/.config/home-manager/home.nix
...
home.packages = with pkgs; [
go
hugo
kubectl
];
...
# Et relancer home-manager
$ home-manager switch
these 7 derivations will be built:
/nix/store/lf5850p7rx4wv461yh07dshxv4hqhd2z-home-manager-path.drv
/nix/store/rncjx9gnxydc93pk99n5l0yk1cbj8wi9-home-manager-fonts.drv
/nix/store/svzzl4ggv97m4gp9kd6ccbc1n4z8qich-hm_LibraryFonts.homemanagerfontsversion.drv
/nix/store/qqp8h0pab3cbz61j311nfbjbjcynwdgw-home-manager-files.drv
/nix/store/ndp6fp78vwj9va3rh1z769583hi9xs4r-home-manager-applications.drv
/nix/store/z36d7w0yfn5ncc3xqnk41i95knv65h9p-activation-script.drv
/nix/store/3hmgp3blqif3jjqi3j1sqgf26wfjs9d1-home-manager-generation.drv
these 5 paths will be fetched (90.7 MiB download, 351.7 MiB unpacked):
/nix/store/kyai650rrywrzflnwda9mbk2c2j9w68r-go-1.26.4
/nix/store/fcwjn7a1j8qiqabrjdg1pkd84m5hk0yv-hugo-0.161.1
/nix/store/cw9mvab1gwgd0lrbf6m026dwa7q843rm-iana-etc-20251215
/nix/store/5ffkf9jl4q5j8lc0hnjbzc8z0z13k2v0-kubectl-1.36.2
/nix/store/xkfjvrsbdm163clwd08ncqfkgsrdzad6-kubectl-1.36.2-man
copying path '/nix/store/xkfjvrsbdm163clwd08ncqfkgsrdzad6-kubectl-1.36.2-man' from 'https://cache.nixos.org'...
copying path '/nix/store/cw9mvab1gwgd0lrbf6m026dwa7q843rm-iana-etc-20251215' from 'https://cache.nixos.org'...
copying path '/nix/store/5ffkf9jl4q5j8lc0hnjbzc8z0z13k2v0-kubectl-1.36.2' from 'https://cache.nixos.org'...
copying path '/nix/store/fcwjn7a1j8qiqabrjdg1pkd84m5hk0yv-hugo-0.161.1' from 'https://cache.nixos.org'...
copying path '/nix/store/kyai650rrywrzflnwda9mbk2c2j9w68r-go-1.26.4' from 'https://cache.nixos.org'...
building '/nix/store/ndp6fp78vwj9va3rh1z769583hi9xs4r-home-manager-applications.drv'...
building '/nix/store/rncjx9gnxydc93pk99n5l0yk1cbj8wi9-home-manager-fonts.drv'...
building '/nix/store/lf5850p7rx4wv461yh07dshxv4hqhd2z-home-manager-path.drv'...
structuredAttrs is enabled
created 0 symlinks in user environment
structuredAttrs is enabled
created 0 symlinks in user environment
building '/nix/store/svzzl4ggv97m4gp9kd6ccbc1n4z8qich-hm_LibraryFonts.homemanagerfontsversion.drv'...
structuredAttrs is enabled
created 175 symlinks in user environment
building '/nix/store/z36d7w0yfn5ncc3xqnk41i95knv65h9p-activation-script.drv'...
building '/nix/store/qqp8h0pab3cbz61j311nfbjbjcynwdgw-home-manager-files.drv'...
building '/nix/store/3hmgp3blqif3jjqi3j1sqgf26wfjs9d1-home-manager-generation.drv'...
/nix/store/l9405c663fv27ycihrr01m4g9zly2hp4-home-manager-generation
Starting Home Manager activation
Activating checkAppManagementPermission
Activating checkFilesChanged
Activating checkLinkTargets
Activating writeBoundary
Activating installPackages
replacing old 'home-manager-path'
installing 'home-manager-path'
building '/nix/store/w53ig4i0kbl8z4i15d15xbmw222axds4-user-environment.drv'...
Activating linkGeneration
Cleaning up orphan links from /Users/jh
Creating home file links in /Users/jh
Activating copyApps
setting up ~/Applications/Home Manager Apps...
Activating onFilesChange
Activating setupLaunchAgentsEt pour installer une version spécifique ?#
Par exemple, pour installer une version spécifique de go :
$ nix-env -qaP go
nixpkgs.go_1_25 go-1.25.11
nixpkgs.go go-1.26.4
nixpkgs.texlivePackages.go go-78116
# Editez votre fichier home.nix et ajoutez le nom du paquet
$ vim /Users/jh/.config/home-manager/home.nix
...
home.packages = with pkgs; [
go_1_25
hugo
kubectl
];
...
# Puis appliquez les changements
$ home-manager switchEt pour installer des versions encore plus anciennes qui sont indisponibles dans l’index nixpkgs 26.05 ? C’est plus compliqué. Je n’ai pas encore eu le temps de creuser cette question ni ressenti le besoin.
Faire du ménage pour éviter la saturation du disque#
À chaque fois que vous lancez la commande home-manager switch, Nix crée une nouvelle génération de votre environnement. Pour éviter la saturation du disque, vous pouvez supprimer les anciennes générations :
$ home-manager generations
2026-07-05 15:36 : id 10 -> /nix/store/jm4g9jrxjjiv39yb24c98ihzpyll0gnc-home-manager-generation (current)
2026-07-05 15:27 : id 9 -> /nix/store/rqx8xiwn35z7y239pnjpzvpbjm916bxi-home-manager-generation
2026-07-05 15:25 : id 8 -> /nix/store/kxx9ky1yrkva9gd3gzmxk2jqlaja2gp6-home-manager-generation
2026-07-05 15:18 : id 7 -> /nix/store/3sz5l00q41kfv2mmdvlcib6n8c0xhwgn-home-manager-generation
2026-07-05 14:46 : id 6 -> /nix/store/wh8ycdkvd3xpi5va3xmc8zla93r3fgin-home-manager-generation
2026-07-05 14:43 : id 5 -> /nix/store/mkbl59xwvzd3yd3x54sl9lsfxwxqf7l6-home-manager-generation
2026-07-05 14:41 : id 4 -> /nix/store/p35dv7cjhslmdzkyg04fk8wh798kb50n-home-manager-generation
2026-07-05 14:37 : id 3 -> /nix/store/2203f2cn3aszn7x5icbp60qakrx8x0rd-home-manager-generation
2026-07-05 14:12 : id 2 -> /nix/store/l9405c663fv27ycihrr01m4g9zly2hp4-home-manager-generation
2026-07-05 13:48 : id 1 -> /nix/store/f6aygwjxr2vl2xb2rr21wp7lz2y0qkkr-home-manager-generationVous pouvez supprimer les générations par leur id, en faisant la commande home-manager remove-generations 1 2 3 4 :
home-manager remove-generations 1 2 3 4
Removing generation 1
Removing generation 2
Removing generation 3
Removing generation 4
home-manager generations
2026-07-05 15:36 : id 10 -> /nix/store/jm4g9jrxjjiv39yb24c98ihzpyll0gnc-home-manager-generation (current)
2026-07-05 15:27 : id 9 -> /nix/store/rqx8xiwn35z7y239pnjpzvpbjm916bxi-home-manager-generation
2026-07-05 15:25 : id 8 -> /nix/store/kxx9ky1yrkva9gd3gzmxk2jqlaja2gp6-home-manager-generation
2026-07-05 15:18 : id 7 -> /nix/store/3sz5l00q41kfv2mmdvlcib6n8c0xhwgn-home-manager-generation
2026-07-05 14:46 : id 6 -> /nix/store/wh8ycdkvd3xpi5va3xmc8zla93r3fgin-home-manager-generation
2026-07-05 14:43 : id 5 -> /nix/store/mkbl59xwvzd3yd3x54sl9lsfxwxqf7l6-home-manager-generationEn plus de la suppression des générations obsolètes, il faut purger le cache nix et le dédupliquer :
nix-collect-garbage
nix store optimiseImportant ! Ne pas lancer la commande nix-collect-garbage sans avoir au préalable supprimé les générations obsolètes : si vous ne le faites pas, aucun espace ne sera libéré, puisque chaque génération aura toujours un lien symbolique vers les packages qu’elle contient.
Gardez toujours au moins trois générations pour pouvoir faire des rollbacks en cas de problème. Libre à vous d’en garder autant que vous le souhaitez.
ZSH et ses extensions#
J’utilise ZSH avec les extensions suivantes :
- la complétion native de zsh (
compinit), activée viaenableCompletion zsh-autosuggestions: suggestions de commandes basées sur l’historiquezsh-syntax-highlighting: coloration syntaxique des commandes
Plutôt que de les installer manuellement, j’ai utilisé home-manager pour les gérer via le fichier home.nix. Les extensions pour zsh ne sont pas à ajouter comme des paquets classiques, mais via des modules spécifiques de home-manager. Cependant, ayant déjà installé zsh et des extensions, j’ai par conséquent déjà un environnement de travail personnalisé. Il faut lancer la commande home-manager switch -b backup pour activer la sauvegarde des fichiers qui seront écrasés par l’installation des extensions gérées par nix :
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
};En ayant ce bloc de configuration, il n’est plus nécessaire d’avoir le paquet zsh dans la liste home.packages = with pkgs;. Le bloc programs.zsh fera implicitement l’installation, telle une dépendance.
L’ancienne configuration personnalisée de zsh (alias, fonctions, etc.) est conservée avec l’extension .backup. Et qu’en est-il des variables d’environnement qui étaient ajoutées dans le fichier .zshrc ? Il est nécessaire de les ajouter dans le fichier home.nix via la propriété home.sessionVariables, pour toutes les variables que vous aviez.
Conclusion#
La migration m’a pris deux heures, dont une à vérifier les correspondances de noms de paquets. Le quotidien est désormais plus simple qu’avec brew : un fichier, une commande, des rollbacks. Le vrai coût n’est pas la migration mais l’apprentissage du modèle Nix — et il ne fait que commencer : nix-shell par projet, packaging maison, et peut-être un jour NixOS sur un serveur du homelab. Si votre Mac est votre outil de travail et que vous pratiquez déjà l’infrastructure as code, le jeu en vaut la chandelle. Sinon, brew fait très bien le travail.
Quelques paquets n’ont soit pas les mêmes noms dans nixpkgs que dans brew, ou ne sont tout simplement pas disponibles dans nixpkgs. Pour les paquets à la marge, l’installation s’est effectuée via l’installeur officiel du projet. Je suis pleinement conscient que cela contrevient à l’esprit de Nix, mais j’ai préféré une migration rapide et fonctionnelle plutôt qu’une recherche exhaustive de solutions alternatives. Au final, je suis content et serein de cette migration ; désormais, plus rien ne bouge sans que je le sache, en plus d’être réutilisable sur n’importe quelle machine, pourvu qu’elle ait nix.
Fichier home.nix#
Voici le fichier home.nix que j’ai utilisé pour configurer mon environnement. Attention : ne mettez jamais de vrais tokens en clair dans ce fichier s’il est destiné à être versionné dans Git — utilisez un gestionnaire de secrets comme sops avec age (présents dans la liste ci-dessous) :
{ config, pkgs, ... }:
{
nixpkgs.config.allowUnfree = true;
home.username = "jh";
home.homeDirectory = "/Users/jh";
home.stateVersion = "26.05"; # Please read the comment before changing.
home.packages = with pkgs; [
age
ansible-lint
btop
bun
cilium-cli
claude-code
discord
ffmpeg
gh
git
go
golangci-lint
gosec
hugo
k9s
kubectl
kubernetes-helm
jq
net-news-wire
nodejs
opencode
opentofu
python3
restic
rtk
rsync
sops
talosctl
tree
typescript
typescript-language-server
vscodium
yamllint
zed-editor
zsh-powerlevel10k
];
home.file.".p10k.zsh".source = ./dotfiles/p10k.zsh;
home.sessionVariables = {
CR_PAT = "redacted";
GITHUB_PERSONAL_ACCESS_TOKEN = "redacted";
SOPS_AGE_KEY_FILE = "/Users/jh/.sops/key.txt";
};
home.sessionPath = [
"$HOME/.local/bin"
"$HOME/.lmstudio/bin"
"$HOME/.codeium/windsurf/bin"
];
programs.home-manager.enable = true;
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
oh-my-zsh = {
enable = true;
theme = "robbyrussell";
plugins = [
"git"
"sudo"
"kubectl"
];
};
# For the p10klevel config file, create a folder,
# do the first init and move the file into this folder
# mkdir -p ~/.config/home-manager/dotfiles
# mv ~/.p10k.zsh ~/.config/home-manager/dotfiles/p10k.zsh
initContent = ''
source ${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/powerlevel10k.zsh-theme
source ~/.p10k.zsh
'';
shellAliases = {
k = "kubectl";
ls = "ls -lath";
rm = "rm -i";
terraform = "tofu";
};
};
}