SkillAgentSearch skills...

Crate2nix

crate2nix builds your cargo-based rust project crate-by-crate with nix

Install / Use

/learn @nix-community/Crate2nix
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

crate2nix

tests-nix-linux tests-nix-macos Crate

crate2nix generates Nix build files for Rust/Cargo projects, building each crate individually for precise, incremental rebuilds.

  • Incremental CI builds -- only rebuild the crates that actually changed.
  • Full Nix integration -- remote builds, binary caches, Docker images, NixOS modules.
  • Local dev unchanged -- keep using cargo and rust-analyzer as usual.

Quick start

Without installing

nix run nixpkgs#crate2nix -- generate
nix build -f Cargo.nix rootCrate.build

With a flake template

nix flake init --template github:nix-community/crate2nix

Installing

# From nixpkgs
nix profile install nixpkgs#crate2nix

# Latest development version
nix profile install github:nix-community/crate2nix

Then, inside your project:

crate2nix generate        # creates Cargo.nix
nix build -f Cargo.nix rootCrate.build

How it works

crate2nix reads Cargo.toml and Cargo.lock, resolves the full dependency tree via cargo metadata, prefetches source hashes, and renders a Cargo.nix file through Tera templates. The generated file contains one Nix derivation per crate, so Nix rebuilds only what changed.

Two generation strategies are supported:

| Strategy | Pros | Cons | | --- | --- | --- | | Manual (crate2nix generate) | No IFD, full build parallelism | Must regenerate when deps change | | Auto (Import From Derivation) | Always in sync with Cargo.lock | May reduce parallelism |

Nix API

tools.nix exposes helpers for use in your own Nix expressions:

let
  crate2nix = builtins.fetchTarball "https://github.com/nix-community/crate2nix/tarball/master";
  tools = import "${crate2nix}/tools.nix" { inherit pkgs; };

  generated = tools.generatedCargoNix {
    name = "my-project";
    src = ./.;
  };

  project = pkgs.callPackage "${generated}/default.nix" {};
in
  project.rootCrate.build

Or the shorthand appliedCargoNix which combines generation and import.

JSON output (experimental)

crate2nix generate --format json emits a pre-resolved JSON file instead of Cargo.nix. All dependency resolution — feature expansion, cfg() platform filtering, optional dep activation — happens in Rust, so the Nix side is a trivial data consumer with no O(n×m) eval-time logic.

Generating

crate2nix generate --format json

This writes ./Cargo.json by default (use -o to override). The output is compact: empty fields and already-resolved feature maps are omitted, so the JSON is typically smaller than the equivalent Cargo.nix.

Consuming in Nix

Use lib/build-from-json.nix (shipped in this repo) to turn the JSON into buildRustCrate derivations:

let
  cargoNix = import ./lib/build-from-json.nix {
    inherit pkgs;
    src = ./.;
    resolvedJson = ./Cargo.json;
  };
in {
  # Single crate
  my-binary = cargoNix.workspaceMembers.my-crate.build;

  # Root crate (if the workspace has one)
  default = cargoNix.rootCrate.build;

  # All workspace members linked together
  all = cargoNix.allWorkspaceMembers;
}

The consumer accepts two optional arguments for customisation:

  • buildRustCrateForPkgs — override the buildRustCrate used (e.g. for a custom toolchain)
  • defaultCrateOverrides — per-crate build fixups, same as the existing Cargo.nix workflow

Documentation

Full documentation is at https://nix-community.github.io/crate2nix/, covering:

Contributing

Contributions are welcome! See the contributing guide for details.

License

Apache-2.0

View on GitHub
GitHub Stars483
CategoryDevelopment
Updated7d ago
Forks110

Languages

Nix

Security Score

100/100

Audited on Mar 25, 2026

No findings