Follow us
Breaking
Software

Replacing Homebrew with Nix flakes and Home Manager

Nix flakes and Home Manager offer a declarative alternative to Homebrew by providing version pinning via flake.lock and automated dotfile management. This approach ensures reproducible developer environments across different machines using the nixpkgs repository.

Share

Homebrew relies on manual commands. You must type brew install to add a package. This process lacks a single source of truth. It does not permit easy version pinning. You often end up with different environments on different machines. I find Homebrew inadequate. It lacks a way to declare dependencies in a single file like a Cargo.toml or package.json. You must manage packages via the CLI with brew install or brew rm. This makes multi-machine management a chore. Homebrew also fails to manage configuration files like your .zshrc or .vimrc. It does not provide lock files to pin specific package versions. If you run brew bundle today, the results differ from running it tomorrow because the package tree state changes. Dependency hell happens when an update to one package silently updates another. This behavior breaks your development environment. Users often find they need separate version managers like pyenv or nvm because Homebrew lacks these features for programming languages. Homebrew also runs slowly due to its architecture. Users encounter issues with Apple Silicon because Homebrew does not prioritize all architectures equally.

Feature Homebrew Nix Flakes
Configuration Manual CLI commands Declarative flake.nix
Version Pinning Difficult / No lock files flake.lock
Project Isolation No nix develop
Dotfile Management No Home Manager
Reproducibility Low High

Nix flakes solve the problem. A flake contains a flake.nix file that defines inputs and outputs. The nixpkgs repository contains about 80,000 packages. The flake.lock file records the exact input revisions. This ensures that two developers on opposite sides of the world get the same results when they run nix build. You can use nix develop to enter a shell with specific versions of NodeJS, Python, or Redis. The command nix develop creates a shell environment that disappears when you exit. This isolation prevents global configuration from cluttering your system. If you use direenv, the environment loads automatically when you enter a project directory. You can also use nix flake update to fetch the latest commits for all your inputs. You can use nix run to run a package without installing it. You can define specific architectures like aarch64-darwin in your flake. The devShells attribute in a flake allows you to define per-system shells. You can use the mkShell function to specify packages to put in your path. This function acts as a wrapper around stdenv.mkDerivation. It provides conveniences like specifying packages instead of nativeBuildInputs. You can use nix flake show to inspect your outputs. You can use nix build to create your environment. You can also use nix run to run a package without installing it. You might wonder if this extra layer of configuration adds too much complexity to your daily workflow?

Home Manager provides a way to manage user-specific configurations and dotfiles. It uses the Nix module system to convert your configuration into a symlinked filesystem under /nix/store. Instead of manually editing files in your home directory, you write them in a home.nix file. For example, you can define your zsh or fish shell settings and all your aliases in one place. This approach replaces the need for tools like Stow or manual git management. When you run home-manager switch, the tool builds a new directory and generates new dotfiles for you, which ensures that nothing ever links to the wrong place or creates collisions in your filesystem. This replacement is complete. You can declare your Neovim configuration or your tmux settings directly in Nix. Home Manager works as a module within a NixOS system configuration. This allows you to build user profiles alongside the system using nixos-rebuild. You can also use it on other Linux distributions by using the standalone tool. You can import existing file-based configurations if you want to shift to Nix gradually. This helps avoid the steep learning curve. I recommend starting with a small configuration before you make it elaborate. You know how frustrating manual management becomes.

Share

Technewsdaily

Senior tech writer covering AI, gadgets and cybersecurity. Breaking down the news that matters, every day.