Using Overlays to add Packages that aren't in Nixpkgs

2025-05-08

Using Overlays to add Packages that aren't in Nixpkgs

It is very common to use overlays in Nix to install packages that aren't available in the standard Nixpkgs repository.

I'll show the process of adding the pokego package that is not in Nixpkgs:

  1. In my flake.nix I have a custom inputs variable within my let block of my flake like so just showing the necessary parts for berevity:
# flake.nix
  outputs = my-inputs @ {
    self,
    nixpkgs,
    treefmt-nix,
    ...
  }: let
    system = "x86_64-linux";
    host = "magic";
    userVars = {
      username = "jr";
      gitUsername = "saylesss88";
      editor = "hx";
      term = "ghostty";
      keys = "us";
      browser = "firefox";
      flake = builtins.getEnv "HOME" + "/flake";
    };

    inputs =
      my-inputs
      // {
        pkgs = import inputs.nixpkgs {
          inherit system;
        };
        lib = {
          overlays = import ./lib/overlay.nix;
          nixOsModules = import ./nixos;
          homeModules = import ./home;
          inherit system;
        };
      };
      # ... snip ...

  1. In the overlay.nix I have this helper function and the defined package:
# overlay.nix
_final: prev: let
  # Helper function to import a package
  callPackage = prev.lib.callPackageWith (prev // packages);

  # Define all packages
  packages = {
    # Additional packages
    pokego = callPackage ./pac_defs/pokego.nix {};
  };
in
  packages
  1. _final: prev:: This is the function definition of the overlay.
  1. let ... in packages: This introduces a let expression, which defines local variables within the scope of this overlay function. The in packages part means that the overlay function will ultimately return the packages attribute set defined within the let block.

  2. callPackage = prev.lib.callPackageWith (prev // packages): This line defines a helper function called callPackage.

  1. packages = { ... };: This defines an attribute set named packages. This set will contain all the new or modified packages introduced by this overlay.

  2. pokego = callPackages ./pac_defs/pokego.nix { };: This is the core of how the pokego package is added.

  1. in packages: As mentioned earlier, the overlay function returns the packages attribute set. When this overlay is applied, the packages defined within this packages set (including pokego) will be added to the overall Nix package set.

The pokego Package definition

The following is the ./pac_defs/pokego.nix, it may be helpful to first read my Package Definitions Explained post to better understand the following:

# pokego.nix
{
  lib,
  buildGoModule,
  fetchFromGitHub,
}:
buildGoModule rec {
  pname = "pokego";
  version = "0.3.0";

  src = fetchFromGitHub {
    owner = "rubiin";
    repo = "pokego";
    rev = "v${version}";
    hash = "sha256-cFpEi8wBdCzAl9dputoCwy8LeGyK3UF2vyylft7/1wY=";
  };

  vendorHash = "sha256-7SoKHH+tDJKhUQDoVwAzVZXoPuKNJEHDEyQ77BPEDQ0=";

  # Install shell completions
  postInstall = ''
    install -Dm644 completions/pokego.bash "$out/share/bash-completion/completions/pokego"
    install -Dm644 completions/pokego.fish "$out/share/fish/vendor_completions.d/pokego.fish"
    install -Dm644 completions/pokego.zsh "$out/share/zsh/site-functions/_pokego"
  '';

  meta = with lib; {
    description = "Command-line tool that lets you display Pokémon sprites in color directly in your terminal";
    homepage = "https://github.com/rubiin/pokego";
    license = licenses.gpl3Only;
    maintainers = with maintainers; [
      rubiin
      jameskim0987
      vinibispo
    ];
    mainProgram = "pokego";
    platforms = platforms.all;
  };
}

Adding the overlay to your configuration

There are a few places you could choose to put the following, I choose to use my configuration.nix because of my setup:

# configuration.nix
nixpkgs.overlays = [inputs.lib.overlays]

Installing Pokego

# configuration.nix
environment.systemPackages = with pkgs; [
  pokego
]
# home.nix
home.packages = [
  pkgs.pokego
]