Adding packages to NixOS on a single system

2 minute read Published: 2018-11-20

So... time to finally add some nix content. This one is probably more along the lines of "did you know ... ?"

Just as a heads up, I'll only be using configuration.nix. I don't like the imparative way of installing packages through nix-env.

When I need to add a package on a single system, that's actually very easy, but it depends a bit on how you want to use it. Let's assume that you just want to add it to environment.systemPackages. That's the setting that will take care of adding binaries to /run/current-system/sw/bin (the main binary path on #NixOS) and also results in *.desktop files being parsed as well for desktop environments.

Here I'm adding the package stored in the file ./pkgs/mbuffer/default.nix to the environment. Note that the path is relative to the nix file you put this code in. So if you add it in /etc/nixos/configuration.nix it refers to /etc/nixos/pkgs/mbuffer/default.nix. If you add it to /etc/nixos/imports/mypkgs.nix instead, and you import that file from configuration.nix, it will refer to /etc/nixos/import/pkgs/mbuffer/default.nix.

environment.systemPackages = with pkgs; [
	vlc
	(callPackage ./pkgs/mbuffer/default.nix {})
];

I like to do it this way, because the pkgs/mbuffer/default.nix has the exact same format as all the other package files found in nixpkgs, so if you want to know the exact format of the file, have a look at this file.

This means that you can easily integrate new packages or changed packages into your own system.

Important: It does not work if the package is used in a service, unless that service gives you the option to explicitly overwrite it, for example like services.nginx. You could overwrite the nginx package by specifiying something like the following in your configuration.nix: services.nginx.package = (callPackage ./pkgs/newnginx/default.nix {})