Generate Nix binary caches without Nix copy

justusw1 pts0 comments

Generate Nix binary caches without nix copy<br>- Justus Perlwitz

Generate Nix binary caches without nix copy

Published: July 29, 2026

Here's how to create a Nix binary cache from a derivation's closure within a Nix derivation. Since you can't run nix commands within derivations, this can be useful for including a build closure within an installation medium, such as when performing a NixOS offline installation.

This method uses the binary-cache function in the nixpkgs repository.

Create the following flake.nix Nix flake file in a new directory and follow along:

# Save as flake.nix<br>description = "Nix binary cache demo";<br>inputs.nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-26.05";<br>inputs.flake-utils.url = "github:numtide/flake-utils";<br>outputs =<br>self,<br>nixpkgs,<br>flake-utils,<br>}:<br>flake-utils.lib.eachDefaultSystem (<br>system:<br>let<br>pkgs = nixpkgs.legacyPackages.${system};<br>modulePath =<br>"${pkgs.path}/pkgs/build-support/binary-cache/default.nix";<br>mkBinaryModule = import modulePath;<br>mkBinaryCache = pkgs.callPackage mkBinaryModule { };<br>rootPaths = [ pkgs.hello ];<br>in<br>packages.default = mkBinaryCache { inherit rootPaths; };<br>);

How the Nix flake works

Before running the script, observe how the Nix flake works.

pkgs.path gives you the path to nixpkgs for your current system within your Nix store. Here's what pkgs.path evalutes to:

$ nix eval nixpkgs#path<br>/nix/store//9fig…-source/

The modulePath variable "${pkgs.path}/pkgs/build-support/binary-cache/default.nix" evaluates to the following:

/nix/store/9fig…-source/pkgs/build-support/binary-cache/default.nix

This is a real path that you can inspect

$ head (nix eval nixpkgs#path)/pkgs/build-support/\<br>binary-cache/default.nix<br>lib,<br>stdenv,<br>coreutils,<br>jq,<br>[…]

import modulePath imports the contents of this binary-cache/default.nix file. To make this a callable function returning a derivation for your very own binary cache, call the imported contents of modulePath with pkgs.callPackage modulePath { }:

# flake.nix<br>modulePath =<br>"${pkgs.path}/pkgs/build-support/binary-cache/default.nix";<br>mkBinaryModule = import modulePath;<br>mkBinaryCache = pkgs.callPackage mkBinaryModule { };

Assign this pkgs.callPackage result to mkBinaryCache and pass to this result the derivations that you want to include in the binary cache with the rootPaths variable. rootPaths here contains pkgs.hello:

# flake.nix<br>rootPaths = [ pkgs.hello ];<br>packages.default = mkBinaryCache { inherit rootPaths; };

pkgs.hello is the nixpkgs version of saying "Hello, world!":

$ nix run nixpkgs#hello<br>Hello, world!

Build the binary cache

Build the binary cache in flake.nix with nix build:

$ nix build

Review the result:

$ ls -la result<br>[…] result -> /nix/store/f5wf…-binary-cache/<br>$tree result -sh<br>[ 56] result<br>├── [ 64] debuginfo<br>├── [ 389] gdz[…]h1d.narinfo<br>├── [ 385] k28[…]d74.narinfo<br>├── [ 64] log<br>├── [ 128] nar<br>│   ├── [1.2M] 0fx[…]5mj.nar.zst<br>│   └── [ 30K] 0xr[…]2c1.nar.zst<br>├── [ 21] nix-cache-info<br>└── [ 64] realisations

5 directories, 5 files

The .nar.zst files contain compressed Nix archive files. The result directory itself contains a Nix store. Inspect the Nix store:

$ nix store info \<br>--store file:///$PWD/result --json<br>"trusted": true,<br>"url": "file:////p/[…]mp.lM00OzLy141/result"

List the Nix archive file contents using zstdcat1 and nix nar ls:

nix nar ls --recursive \<br>(zstdcat result/nar/0fx[…]5mj.nar.zst | psub) /

Output:

./bin<br>./bin/iconv<br>./lib<br>./lib/i18n<br>./lib/i18n/libBIG5.dylib<br>[…]<br>./share/man/man3/iconvlist.3.gz

Here are the contents of the second Nix archive:

nix nar ls --recursive \<br>(zstdcat result/nar/0xr[…]2c1.nar.zst | psub) /

Output:

./bin<br>./bin/hello<br>./share<br>./share/info<br>./share/info/hello.info<br>./share/man<br>./share/man/man1<br>./share/man/man1/hello.1.gz

"zstdcat - Compress or decompress .zst files" on man.uex.se. Make available with nix shell nixpkgs#zstd ↩

I would be thrilled to hear from you! Please share your thoughts and ideas<br>with me via<br>email.

Back to Index

pkgs binary cache flake result nixpkgs

Related Articles