My first overlay, for emacs

In the course of [trying to install org-roam for Emacs]((emacsPackages.org-roam: init at 0.1.2 by rasendubi · Pull Request #80280 · NixOS/nixpkgs · GitHub), I’ve realized that I have to understand overlays.

Questions about the NixOS wiki page on overlays

The first section, “Applying overlays manually”, includes just the code snippet import <nixpkgs> { overlays = [ overlay1 overlay2 ]; }. Where would one use that? In the configuration.nix file? From the nix repl?

The next section, “Applying overlays automatically”, includes “user level” and “system level” subsections. I’m the only user of my system, and the only way I ever build is via sudo, so I’m interested in the system level, right?

If so, in the “system level” subsection it says, “If you want your overlays to be accessible by nix tools and also in the system-wide configuration, add nixpkgs-overlays to your NIX_PATH:”

NIX_PATH="$NIX_PATH:nixpkgs-overlays=/etc/nixos/overlays"

That looks like a bash command. Is there some bash file that gets loaded every time I start the OS, to which I should add that line? I don’t see .bashrc or .bash_profile in my home directory.

Then there’s a third subsection called “Using nixpkgs.overlays from configuration.nix as in your NIX_PATH”. Is that an alternative to the “system level” section earlier? It’s the only one that mentions the configuration.nix file.

My .nix files do not mention nix.nixPath, so it seems like I should add this:

  nix.nixPath =
    # Prepend default nixPath values.
    options.nix.nixPath.default ++
    # Append our nixpkgs-overlays.
    [ "nixpkgs-overlays=/etc/nixos/overlays-compat/" ]
  ;

and then put this code into /etc/nixos/overlays-compat/overlays.nix:

self: super:
with super.lib;
let
  # Load the system config and get the `nixpkgs.overlays` option
  overlays = (import <nixpkgs/nixos> { }).config.nixpkgs.overlays;
in
  # Apply all overlays to the input of the current "main" overlay
  foldl' (flip extends) (_: super) overlays self

Questions about using emacs-overlay

The emacs-overlay README says that “probably the most convenient way to pull in this overlay is by just fetching the tarball of latest master on rebuild”, and provides the following code for doing so:

{
  nixpkgs.overlays = [
    (import (builtins.fetchTarball {
      url = https://github.com/nix-community/emacs-overlay/archive/master.tar.gz;
    }))
  ];
}

Where does that code go? Should I create an emacs-overlay.nix file in /etc/nixos/overlays-compat/, containing that code and nothing else? Will the foldl' (flip ... line in overlays.nix find and incorporate it?

Would be nice to link it here.

Anywhere you would use import <nixpkgs> { }. Most prominently in shell.nix but it is a Nix expression so it can be used anywhere in Nix.

NixOS configurations built by sudo nixos-rebuild will only respect overlays set by nixpkgs.overlays, globally through NIX_PATH or locally for the root user (see https://github.com/NixOS/nixpkgs/blob/d903f1166b967c6a10de5fcc8cec1798be5b55ff/pkgs/top-level/impure.nix#L44-L57).

Yes, that is shell expression. You could set it in environment.extraInit NixOS option or environment.sessionVariables. Or you can just use nix.nixPath option which also sets the environment variable globally. (Note that the latter two set the environment variable rather to append to it so you might need to add some items from the default $NIX_PATH like nixos-config=/etc/nixos/configuration.nix.)

There are actually three ways to set up overlays and different tools support different methods.

There is nixpkgs.overlays option, which sets up the overlays for the pkgs attribute passed to NixOS modules like configuration.nix. But tools like nix-build do not see it.

Then there is the local variant (path under your home directory) that nix-{build,env,shell} run as your user see.

And then there is the global variant (path pointed by nixpkgs-overlays in NIX_PATH environment variable) that nix-{build,env,shell} see.

The “Using nixpkgs.overlays from configuration.nix as in your NIX_PATH” section shows how to make the overlays you set through nixpkgs.overlays visible in the global variant.

That uses nixpkgs.overlays option so it should go to a NixOS module like your configuration.nix.

I also found out over here at nixos-emacs, that I can choose the separate file per overlay approach (i. e. ~/.config/nixpkgs/overlays/emacs.nix) as in:

# ~/.config/nixpkgs/overlays/emacsGit.nix
self: super:
{
  inherit ((import (builtins.fetchTarball {
      url = https://github.com/nix-community/emacs-overlay/archive/7678979b3ca51bf557b6bbe2a5b8aa8c4082ff26.tar.gz;
  })) self super) emacsGit;
}