nixpkgs-review builds only the packages a nixpkgs pull request touches, then hands you a shell
Review pull-requests on https://github.com/NixOS/nixpkgs
At a glance
- What is it?
- nixpkgs-review is a Python tool for reviewing pull requests against the NixOS nixpkgs repository. It builds the changed packages, drops you into a shell with the successful builds on PATH, and can post the results as a pull request comment. It is packaged in nixpkgs itself, needs a local nixpkgs checkout, and the workflow assumes you are a nixpkgs contributor.
- Who is it for?
- Adopt nixpkgs-review if you contribute to nixpkgs or maintain a large set of Nix packages and want a local build of the exact packages a pull request touches before approving it. Do not adopt it as a general CI system or a way to test an application against a changed library, because it works against nixpkgs pull requests specifically and needs a full nixpkgs checkout.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
It builds the changed packages, not the whole tree
nixpkgs-review exists to review pull requests against the NixOS nixpkgs repository, and the README states in one sentence what it does: it automatically builds packages changed in the pull requests. That is the whole idea, and it is a substantial saving in a repository the size of nixpkgs, where building everything is not an option.
The feature list spells out the supporting capabilities. There is ofborg support, which reuses the evaluation output of CI to skip local evaluation but also falls back if ofborg is not finished. There is remote builder support, so the actual compilation can happen on other machines. You can build a subset of packages, which the README calls great for mass-rebuilds, and you can build nixos tests. Output is available as markdown reports, with logs per built or failed package, and built packages are symlinked into a result directory for inspection.
The GitHub integration is what turns it from a build script into a review tool. It can post pull request comments with the results, approve or merge pull requests, and show pull request comments and reviews. The README is explicit that merging requires maintainer permission, so the merge path is gated on your credentials rather than on the tool.
The project is a Python package with the entry point nixpkgs_review:main, exposed as two console scripts, nixpkgs-review and nix-review. The pyproject.toml targets Python 3.12 for ruff and mypy, and mypy runs in strict mode with no_implicit_optional enabled. It is classified as Development Status :: 5 - Production/Stable, and the licence recorded in the pyproject.toml is MIT with a LICENSE.md at the repository root, a permissive grant with no copyleft obligation on scripts you write around it.
Three ways to get it: nix run, nix-build, or the repo checkout
nixpkgs-review is included in nixpkgs, so the shortest route needs no installation at all:
$ nix run 'nixpkgs#nixpkgs-review' -- pr <PR number>For working from the git repository, the README shows the two command build:
$ nix-build
$ ./result/bin/nixpkgs-reviewThere is a third path aimed at IDE users, since a Python project with a nix devshell is awkward to open otherwise:
$ nix-build -A env -o .venvThat produces an environment in .venv, and the README notes you can also just use the script in the bin directory directly, shown as ./bin/nixpkgs-review, which matches the bin/ entry in the repository layout.
The repository is structured for a Nix-first workflow. There is a flake.nix and flake.lock, a default.nix, a devshell.nix, a treefmt.nix for formatting, an .envrc for direnv, and a .mergify.yml for the merge automation. The Python package data section includes nixpkgs_review = ["nix/*.nix"], so the Nix expressions ship with the package rather than being fetched at runtime.
The pytest configuration sets addopts to -n auto, so the test suite runs in parallel, and the ruff configuration selects ALL rules with a documented ignore list, which is a reasonable way to describe a project that treats linting as part of the definition of done.
The review flow starts in your nixpkgs checkout, and that checkout matters
Before anything else you change into your local nixpkgs repository directory, and the README gives the command as cd ~/git/nixpkgs. There is a warning attached to that step that catches people out. If you have shallow cloned nixpkgs with git clone --depth, nixpkgs-review may be unable to perform merges due to missing merge base commits, and the fix is to reclone without the --depth flag.
That constraint is worth understanding rather than just obeying. The tool merges the pull request against your local tree, and a merge needs a common ancestor, which a shallow clone does not have. It is the one setup step that will block you with a confusing error if you skip it.
Your checkout is safe, and the README says so explicitly: your local checkout git will not be affected by nixpkgs-review, since it uses git-worktree to perform fast checkouts. The worktree lives under a .review directory in the nixpkgs checkout, with a name derived from the pull request number, and the fetch goes into a dedicated ref namespace rather than your branches.
Once you are in the right directory, you give it either a pull request number or the full URL, and both are documented:
$ nixpkgs-review pr 37242$ nixpkgs-review pr https://github.com/NixOS/nixpkgs/pull/37242The output shows the whole mechanism in sequence. It fetches the pull request head into refs/nixpkgs-review/0, creates a worktree at .review/pr-37242, checks out the files, and then runs nix-build with --keep-going and --max-jobs 4 and the sandbox option enabled, building the specific attribute such as -A redis. The README's example ends with the built package's store path and a nix-shell invocation that confirms the redis-cli version inside the build environment.
Reviewing a local commit or uncommitted work needs no pull request
Not every review is a remote pull request, and the tool has separate entry points for the other two cases. To review a local commit, you use the rev command:
$ nixpkgs-review rev HEADInstead of HEAD, a commit or a branch can also be given. For changes that are not committed at all, the wip command handles it:
$ nixpkgs-review wipAnd staged changes specifically are covered by an extra flag on the same command:
$ nixpkgs-review wip --stagedThe wip mode is the one that makes this tool useful beyond pull request triage. When you are in the middle of editing a package expression, you can build it in isolation, with the same isolation the pull request path gives you, without pushing a branch or opening anything.
The three commands share the same result reporting, and the flags for reporting are worth noting because they work across modes. The --post-result flag posts the results as a formatted pull request comment, and it takes a pull request number:
$ nixpkgs-review pr --post-result 37242Log snippets for failed builds can be excluded with --no-logs, which matters when a build failure produces a large amount of output that would bury the useful part of the comment. The --print-result flag does the opposite of posting and writes the report to the terminal instead, and the README says that flag works with the rev and wip commands as well, though the sentence describing it is cut off mid-word.
The review shell is where approval and merging happen
After the build, nixpkgs-review normally starts your $SHELL with the built packages on PATH, so you can poke at the result interactively. That shell is also the entry point for the GitHub actions, and the README gives the exact sequence for the case where you have read a diff and want to say it looks good provided there are no build failures:
$ nixpkgs-review pr 37242
review-shell> nixpkgs-review approve
review-shell> nixpkgs-review merge
review-shell> nixpkgs-review post-result
review-shell> nixpkgs-review commentsThe merge subcommand is the one that needs maintainer access, as the comment in the example notes, and it is conditional on there being no build failures.
The approve, merge, post-result and comments subcommands are therefore not separate tools, they are commands inside the review environment. That is a deliberate design: the same session that built the packages is the session where you record your verdict, so the result and the decision cannot drift apart.
For scripted use, the shell is optional. The --no-shell command lets nixpkgs-review run non-interactively, which the README says allows for batch processing of multiple reviews or use in scripts and bots. The example loops over a range of pull request numbers, runs each with --no-shell and --post-result, and prints whether the pull request succeeded or failed. A --run flag goes further and runs a custom command through bash -c in that environment instead of an interactive session, and the sample passes jq against a report.json.
The --run example also shows the shape of the report, which is a JSON object with a checkout field of merge, the extra-nixpkgs-config, the pull request number, and a result object keyed by system. Each system lists blacklisted, broken, built, failed, non-existent and tests, so a bot can decide pass or fail per architecture.
Optional tools change the output, not the results
Three external tools are picked up automatically if they are on your PATH, and this is a design choice worth noting because it means the tool adapts to your environment rather than insisting on its own.
nix-output-monitor, the nom binary, is used by default when found, providing a more user-friendly build output with progress tracking and cleaner formatting. If you have nom installed but do not want it, you can pass nix to --build-graph to use nix build instead of nom build. That flag name is a little misleading for what it does, since it selects the build front end rather than describing a graph.
glow is used to render markdown content such as pull request descriptions with syntax highlighting and formatting in the terminal. delta is used to display git diffs with enhanced visualisation, including side-by-side comparisons and syntax highlighting. Neither changes what gets built; they change how the output reads.
There is also a configuration escape hatch for packages that need special treatment. Some pull requests require configuration for nixpkgs to test out, and the --extra-nixpkgs-config flag supplies extra configuration for nixpkgs:
$ nixpkgs-review pr 37242 --extra-nixpkgs-config '{ cudaSupport = true; }'The example is a hardware support flag, which is the kind of case that would otherwise fail to evaluate on a machine without the relevant hardware. The report echoes the value back under extra-nixpkgs-config, so a scripted consumer can see what was applied.
One more flag matters for correctness: --systems all, as used in the --run example, selects which systems to build for. The default report shows x86_64-linux and aarch64-linux, so the default already covers both, and the flag is how you widen or narrow that set.
What the tool assumes about you
The clearest limitation is that this is a contributor tool, not a general purpose CI runner. Every command is scoped to nixpkgs. The configuration, the git worktree layout under .review, the ref namespace refs/nixpkgs-review, the ofborg integration, the ability to approve and merge pull requests, and the mention of nixos tests all point the same way.
The second limitation is the environment. nixpkgs-review needs a local nixpkgs clone that is not shallow, the Nix tooling, and enough disk and CPU to build the changed packages. The README's example uses --max-jobs 4, and remote builder support is there for when the local machine is not enough. The mass-rebuild capability, which the README calls great, is exactly the case where you need those remote builders.
The third is the output verbosity question. Failed builds produce logs, and the --no-logs flag exists precisely because those logs can be long. For a pull request that touches a package with a large build output, you will want to choose deliberately between a comment with the logs and a comment without them.
On maintenance, the picture is healthy. The last push was on 2026-10-17, the repository is not archived, and the release history shows 4.0.0 on 2026-09-07, 3.9.0 on 2026-06-23 and 3.8.0 on 2026-05-11. The version numbers are moving at a reasonable pace, and the topics list includes build-with-buildbot, hacktoberfest and managed-by-renovate, which says the project accepts outside contributions and keeps its own dependencies current.
The alternative worth comparing is building the changed attributes yourself with nix-build and reading the CI logs. That works and it needs no extra tool, but you lose the worktree isolation, the shell with the built packages on PATH, the markdown report, the pull request comment and the approve and merge path, and you hand the merge base problem yourself.
Editorial conclusion
Adopt nixpkgs-review if you contribute to nixpkgs or maintain a large set of Nix packages and want a local build of the exact packages a pull request touches before approving it. Do not adopt it as a general CI system or a way to test an application against a changed library, because it works against nixpkgs pull requests specifically and needs a full nixpkgs checkout. Verify first that your nixpkgs clone is not shallow, since a shallow clone can leave it unable to merge because merge base commits are missing, and note that approving and merging require a token with maintainer permission.
Frequently asked questions
How do I install nixpkgs-review?
It is included in nixpkgs, so you can use nix run 'nixpkgs#nixpkgs-review' without installing anything, or run nix-build in the git repository and use ./result/bin/nixpkgs-review. For IDE support, nix-build -A env -o .venv produces a development environment.
Why does nixpkgs-review need a full nixpkgs clone?
It merges the pull request against your local tree, and a merge needs a common ancestor. If you shallow cloned nixpkgs with git clone --depth, it may be unable to perform merges due to missing merge base commits, so the README says to reclone without the --depth flag. Your checkout is not modified, since git-worktree is used for the fast checkout.
How do I post nixpkgs-review results as a pull request comment?
Pass the --post-result flag with the pull request number, for example nixpkgs-review pr --post-result 37242. You can add --no-logs to exclude log snippets for failed builds, or use --print-result to print the report to the terminal instead of posting it.
Can nixpkgs-review review local changes instead of a pull request?
Yes. Use nixpkgs-review rev HEAD to review a local commit or branch, and nixpkgs-review wip to review uncommitted changes, with --staged to limit it to staged changes. The reporting flags work with the rev and wip commands too.
How do I approve or merge a pull request with nixpkgs-review?
From inside the review shell that nixpkgs-review starts, run nixpkgs-review approve or nixpkgs-review merge, the latter provided there are no build failures and you have maintainer access. The same shell offers post-result and comments. For automation, --no-shell and --run allow the whole flow to run without an interactive session.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mic92-nixpkgs-review)Was this useful?