lastlog.de/blog
  • timeline
  • about
  • roadmap
  • websocket
  • drafts
  • special pages
  • login
prev. article next article
libnix

libnix rust v3 release

11 oct 2026

nixlibnixcargorustcargo+libnix

motivation

this is a short status update on cargo (libnix) covering what changed since the libnix-1.87.0+v1 release. two releases happened since then: libnix-1.87.0+v2 and libnix-1.87.0+v3.

the code can be found here:

https://github.com/nixcloud/cargo/blob/master-libnix/README.md

improvements

talking to the nix-daemon directly

cargo build with the nix backend no longer spawns nix build as a subprocess. instead it evaluates the build system with nix-instantiate and then talks the nix worker protocol to the nix-daemon directly, sending a single build request for the target and all its dependencies.

the daemon reports a structured result per crate, so cargo knows exactly which crate failed, which ones were skipped because of it and which ones came from a binary cache. -j and --keep-going are passed on to the daemon.

logone is now part of cargo

the external logone crate was replaced by an in-tree renderer that reads the daemon’s log stream:

   Evaluated target in 1.4s
 Downloading serde 1.0.218
   Compiling proc-macro2 (build.rs run)
   Compiling serde
[ 51 Done | 613 Expected | 8 Running | 0 Failed ] fiat-crypto, jiff (×2), libc (build.rs build)
  • Compiling, Building and Downloading lines similar to vanilla cargo
  • rustc diagnostics are shown as cargo would show them
  • failed crates come with their build log, dependents are listed as skipped
  • a status line with correct counts (nix’s own counter overcounts)
  • the time spent evaluating the nix build system is printed

parallel builds again

dependency flags of build scripts used to be read with builtins.readFile at evaluation time, which forced crates to be built one after another. the flags are now collected in the buildPhase into a rustc response file, so nix schedules independent crates in parallel again (#11).

support for IFD

cargo build write-nix-buildsystem now only needs --out-dir. without --url/--hash the generated build system points to the local project directory, so it can be generated inside a derivation and imported (#22):

CARGO_BACKEND=nix cargo build --offline write-nix-buildsystem --out-dir $out

cargo_build_caller.nix takes project_root and system as arguments and evaluates in pure (flake) mode, so a flake can build any rust project from its own source this way. the flake.nix of the cargo fork uses this to build cargo (libnix) from the current checkout: nix build .#cargo-libnix-master-via-ifd.

the export with --url/--hash for releases still works as before.

crates live in the nix store

in nix mode cargo never downloads a crate itself anymore (#24). each crates.io crate is fetched into the nix store by the nix-daemon, under the same store path the generated build system’s fetchurl uses. so crate sources are fetched once and shared between cargo and the nix build, and they can come from cache.nixos.org.

~/.cargo/registry/cache stays empty and -v shows the store path next to each Downloading line.

without the nix-daemon socket cargo stops with an error, there is no fallback to cargo’s own downloads.

no more crates.io index for offline builds

with --offline and a Cargo.lock the resolver no longer needs the crates.io index. crates.io is served from the crate tarballs in the nix store instead (#22).

this means the IFD from above needs no vendoring and no network, the crate tarballs only have to be inputs of the derivation. they can be computed from Cargo.lock in plain nix:

lock = builtins.fromTOML (builtins.readFile ./Cargo.lock);
crateTarballs = map (p: pkgs.fetchurl {
    name = "crate-${p.name}-${p.version}.tar.gz";
    url = "https://crates.io/api/v1/crates/${p.name}/${p.version}/download";
    sha256 = p.checksum;
  })
  (builtins.filter (p: (p.source or "") == "registry+https://github.com/rust-lang/crates.io-index") lock.package);

smaller things

  • nixpkgs 26.05 and an updated fenix
  • cargo --version reports cargo 1.87.0 +libnix
  • nix develop works better: PATH, CA certificates and proxies are passed to nix
  • the dev shell uses the libnix-1.87.0+v2 release as its default cargo
  • a clearer error when target/nix lacks the .cargo-libnix-managed marker (#17)

experiments

the branch 20_using_nix_content_addressed marks the build.rs run derivations as content addressed (__contentAddressed = true), so a build script that produces the same output doesn’t trigger rebuilds downstream (#20). this needs the ca-derivations experimental feature, so it is not merged.

ui example

this shows the cargo build after a nix-collect-garbage -d so it also includes downloads of the toolchain, dependencies and the build of the main application.

summary

cargo (libnix) is still slower than vanilla cargo, but the logging, the sharing of crates and builds via the nix store and now the IFD support make it a pleasant way to build rust projects with nix.

if you like this work, your support is needed!

  • consider a star at https://github.com/nixcloud/cargo/stargazers to show your support.
  • comments are welcome in https://discourse.nixos.org/t/libnix-feedback/75193
  • if you’re interested in supporting this development, please reach out to me, see https://lastlog.de/cv for details.
article source