Nix Flake Checker is a tool from Determinate Systems that performs "health" checks on the flake.lock
files in your flake-powered Nix projects.
Its goal is to help your Nix projects stay on recent and supported versions of Nixpkgs.
To run the checker in the root of a Nix project:
nix run github:DeterminateSystems/flake-checker
# Or point to an explicit path for flake.lock
nix run github:DeterminateSystems/flake-checker /path/to/flake.lock
Nix Flake Checker looks at your flake.lock
's root-level Nixpkgs inputs.
There are two ways to express flake policies:
If you're running it locally, Nix Flake Checker reports any issues via text output in your terminal. But you can also use Nix Flake Checker in CI.
At any given time, Nixpkgs has a bounded set of branches that are considered supported. The current list:
nixos-23.11
nixos-23.11-small
nixos-24.05
nixos-24.05-small
nixos-unstable
nixos-unstable-small
nixpkgs-23.11-darwin
nixpkgs-24.05-darwin
nixpkgs-unstable
By default, Flake Checker verifies that:
NixOS
org as the GitHub owner (and thus that the dependency isn't a fork or non-upstream variant).You can adjust this behavior via configuration (all are enabled by default but you can disable them):
Flag | Environment variable | Action | Default |
---|---|---|---|
--check-outdated |
NIX_FLAKE_CHECKER_CHECK_OUTDATED |
Check for outdated Nixpkgs inputs | true |
--check-owner |
NIX_FLAKE_CHECKER_CHECK_OWNER |
Check that Nixpkgs inputs have NixOS as the GitHub owner |
true |
--check-supported |
NIX_FLAKE_CHECKER_CHECK_SUPPORTED |
Check that Git refs for Nixpkgs inputs are supported | true |
You can apply a CEL condition to your flake using the --condition
flag.
Here's an example:
flake-checker --condition "has(numDaysOld) && numDaysOld < 365"
This would check that each Nixpkgs input in your flake.lock
is less than 365 days old.
These variables are available in each condition:
Variable | Description |
---|---|
gitRef |
The Git reference of the input. |
numDaysOld |
The number of days old the input is. |
owner |
The input's owner (if a GitHub input). |
supportedRefs |
A list of supported Git refs (all are branch names). |
We recommend a condition at least this stringent:
supportedRefs.contains(gitRef) && (has(numDaysOld) && numDaysOld < 30) && owner == 'NixOS'
Note that not all Nixpkgs inputs have a numDaysOld
field, so make sure to ensure that that field exists when checking for the number of days.
Here are some other example conditions:
# Updated in the last two weeks
supportedRefs.contains(gitRef) && (has(numDaysOld) && numDaysOld < 14) && owner == 'NixOS'
# Check for most recent stable Nixpkgs
gitRef.contains("24.05")
You can automate Nix Flake Checker by adding Determinate Systems' Nix Flake Checker Action to your GitHub Actions workflows:
checks:
steps:
- uses: actions/checkout@v4
- name: Check Nix flake Nixpkgs inputs
uses: DeterminateSystems/flake-checker-action@main
When run in GitHub Actions, Nix Flake Checker always exits with a status code of 0 by default—and thus never fails your workflows—and reports its findings as a Markdown summary.
The goal of Nix Flake Checker is to help teams stay on recent and supported versions of Nixpkgs. The flake checker collects a little bit of telemetry information to help us make that true.
Here is a table of the telemetry data we collect:
Field | Use |
---|---|
distinct_id |
An opaque string that represents your project, by sha256 hashing repository and organization details. |
version |
The version of Nix Flake Checker. |
is_ci |
Whether the checker is being used in CI (GitHub Actions). |
disallowed |
The number of inputs using unsupported branches of Nixpkgs. |
outdated |
The number of inputs using outdated versions of Nixpkgs. |
non_upstream |
The number of inputs using forks of Nixpkgs. |
To disable diagnostic reporting, set the diagnostics URL to an empty string by passing --no-telemetry
or setting FLAKE_CHECKER_NO_TELEMETRY=true
.
You can read the full privacy policy for Determinate Systems, the creators of this tool and the Determinate Nix Installer, here.
The Nix Flake Checker is written in Rust.
This repo exposes a parse-flake-lock
crate that you can use to parse flake.lock
files in your own Rust projects.
To add that dependency:
[dependencies]
parse-flake-lock = { git = "https://github.com/DeterminateSystems/flake-checker", branch = "main" }
Here's an example usage:
use std::path::Path;
use parse_flake_lock::{FlakeLock, FlakeLockParseError};
fn main() -> Result<(), FlakeLockParseError> {
let flake_lock = FlakeLock::new(Path::new("flake.lock"))?;
println!("flake.lock info:");
println!("version: {version}", version=flake_lock.version);
println!("root node: {root:?}", root=flake_lock.root);
println!("all nodes: {nodes:?}", nodes=flake_lock.nodes);
Ok(())
}
The parse-flake-lock
crate doesn't yet exhaustively parse all input node types, instead using a "fallthrough" mechanism that parses input types that don't yet have explicit struct definitions to a serde_json::value::Value
.
If you'd like to help make the parser more exhaustive, pull requests are quite welcome.