nova-nix: Windows-native Nix implementation in Haskell and C99

[ apache, distribution, library, nix, program, system ] [ Propose Tags ] [ Report a vulnerability ]

An implementation of Nix for Windows, written in Haskell with a C99 data layer that keeps evaluation data off the GHC heap. It also runs on macOS and Linux. It has its own parser, lazy evaluator, store, derivation builder and binary-cache substituter, and does not need an existing Nix installation.

On the derivations its CI checks, over pinned pairs of Nix and nixpkgs, the derivation paths it computes match upstream's. On Windows it builds packages from source through a stage-1 stdenv over prebuilt MinGW-w64 and MSYS2 packages pinned by SHA-256, and builds GNU Mes from a 1,623-byte seed. The project is experimental; see the README for what is not implemented.

Evaluation needs the C data layer, so library code must run it between Nix.Eval.Arena.arenaInit and Nix.Eval.Arena.arenaDestroy.

Built on nova-cache for NAR serialization, narinfo handling, and Ed25519-signed binary substitution.


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1.0.0, 0.1.0.1, 0.1.1.0, 0.1.2.0, 0.1.3.0, 0.1.4.0, 0.1.5.0, 0.1.6.0, 0.1.7.0, 0.1.7.1, 0.1.8.0, 0.1.9.0, 0.2.0.0, 0.3.0.0, 0.4.0.0, 0.5.0.0, 0.6.0.0, 0.8.0.0, 0.9.0.0, 0.10.0.0
Change log CHANGELOG.md
Dependencies array (>=0.5 && <0.6), base (>=4.22 && <5), bytestring (>=0.11 && <0.13), containers (>=0.6 && <0.9), crypton (>=1.1 && <2), directory (>=1.3.8 && <1.4), file-io (>=0.1.1 && <0.2), filelock (>=0.1.1 && <0.2), filepath (>=1.4.100 && <1.6), http-client (>=0.7 && <0.8), http-client-tls (>=0.3 && <0.5), http-types (>=0.12 && <0.13), mtl (>=2.2 && <2.4), nova-cache (>=0.11.1.1 && <0.13), nova-nix, process (>=1.6 && <1.7), ram (>=0.20 && <1), random (>=1.2 && <1.4), regex-tdfa (>=1.3 && <1.4), sqlite-simple (>=0.4 && <0.5), tar (>=0.7.1 && <0.8), text (>=2.0 && <2.2), time (>=1.9 && <1.17), unix (>=2.8 && <2.9), Win32 (>=2.9 && <2.15), zlib (>=0.7 && <0.8), zstd (>=0.1 && <0.2) [details]
Tested with ghc ==9.14.1
License Apache-2.0
Copyright 2026 Novavero AI Inc.
Author Devon Tomlin
Maintainer devon.tomlin@novavero.ai
Uploaded by aoinoikaz at 2026-11-05T16:05:10Z
Category Nix, Distribution, System
Home page https://github.com/Novavero-AI/nova-nix
Bug tracker https://github.com/Novavero-AI/nova-nix/issues
Source repo head: git clone https://github.com/Novavero-AI/nova-nix -b main
Distributions
Executables nova-nix
Downloads 392 total (94 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for nova-nix-0.10.0.0

[back to package description]

nova-nix

CI Hackage License

nova-nix is an implementation of Nix that runs natively on Windows, without WSL or an existing Nix installation: the same language, the same /nix/store paths as upstream Nix on Linux and macOS, and the same binary caches. It is written in Haskell with a C99 data layer, has its own parser, evaluator, store, builder and binary-cache substituter, and also runs on macOS and Linux.

nova-nix is experimental. Read Limitations before relying on it.

Status

  • Evaluation matches upstream Nix on the cases CI checks. On every change, CI evaluates the nixpkgs derivations in drvpath-cases.txt and the expressions in eval-cases.sh with nova-nix and with upstream Nix, on each pairing of Nix and nixpkgs that parity.yml pins, and requires the same results. A matching drvPath means the whole build-time closure behind it matches too. It also probes derivation against upstream's over a corpus of calls, apart from the differences derivation-divergences.txt lists. How much of the rest of nixpkgs evaluates is not measured (#29).
  • Windows builds run natively. CI builds GNU Hello on Windows through a stage-1 stdenv whose toolchain is prebuilt MinGW-w64 and MSYS2 packages, each pinned by SHA-256 (pkgs/windows/bootstrap). Replacing them with a toolchain built from source is tracked in #26. CI builds the start of it on x64 and ARM64 Windows from the 1,623-byte seed of stage0-pe32: the chain up to kaem, mescc-tools-extra, and a Windows port of GNU Mes 0.27.1.
  • Binary caches work in both directions. nova-nix push uploads a closure to a nova-cache server, which signs it, and a build given a substituter downloads signed NARs from an HTTP binary cache instead of building. CI substitutes from a local nova-cache server on Linux. On every push to main it publishes the Windows Hello closure to the public cache at cache.novavero.ai, then builds that closure into an empty store with the cache as its only substituter and fails if any path is built locally.

Limitations

  • No flakes, no nix-shell or nix develop, and no daemon or multi-user mode.
  • Evaluation is slower than upstream's, most of all on large evaluations such as a NixOS system. The Parity job logs both evaluators' times for each derivation case.
  • Garbage collection has no runtime roots: nova-nix store gc keeps what build --out-link registered and what the operator roots under the store's .nova-nix/gcroots, not what a running program has open. keep-derivations and keep-outputs are not implemented, so a rooted output does not keep the .drv that built it. build creates no result link unless --out-link is given, where nix-build defaults to ./result.
  • --restrict-eval and --pure-eval, and restrict-eval, pure-eval and allowed-uris in nix.conf, gate reads, the environment and fetches as upstream's modes do, with three differences: the closure of a search path root that is a store path is not allowed along with it, builtins.findFile treats a path the policy refuses as absent, and under --pure-eval builtins.nixPath lists the bundled <nix/*> directory, where upstream's is empty.
  • builtins.fetchurl runs curl, builtins.fetchTarball runs sh, curl and tar, and builtins.fetchGit runs git, each from PATH.
  • A store path's hash covers the spelling of the store directory. On Windows nova-nix hashes over /nix/store, as Linux and macOS do. Upstream's local store on Windows hashes over its native directory, %ProgramData%\nix\store by default since Nix 2.35, so the same derivation has a different store path in each.
  • On Windows a build's process tree runs in a job object, so stopping a build stops everything it started. No platform isolates a build's filesystem or network; a Windows filesystem sandbox is tracked in #194.
  • nova-nix itself needs neither WSL nor Cygwin, but the Windows stdenv runs its build scripts with MSYS2's bash.
  • Store paths that contain symlinks need Windows Developer Mode or an elevated shell. nova-nix creates native symlinks and fails rather than falling back to a copy.

Install

Each release has an archive per platform:

Platform Archive
Linux x86_64 nova-nix-linux-x64.tar.gz
macOS arm64 nova-nix-macos-arm64.tar.gz
Windows x86_64 nova-nix-windows-x64.zip

Each archive unpacks to a single directory holding bin/, share/nova-nix/, pkgs/ and the license files. share/nova-nix/ provides the <nix/*> search path, so the binary works wherever the directory is unpacked, and pkgs/ holds the package recipes. Check the download against the SHA256SUMS file attached to the same release, with sha256sum --ignore-missing -c SHA256SUMS.

In a GitHub Actions workflow:

- uses: Novavero-AI/install-nova-nix@v1
- run: nova-nix eval --expr '1 + 2'

Usage

$ nova-nix eval --expr '1 + 2'
3
$ nova-nix build FILE.nix -A ATTR --out-link result
$ nova-nix build FILE.nix --substituter URL --trusted-key KEY --fallback
$ nova-nix store gc

nova-nix --help lists every command and flag.

Building GNU Hello on Windows, from the unpacked release directory, with the public cache as its substituter:

> bin\nova-nix build pkgs\windows\hello.nix --substituter https://cache.novavero.ai --trusted-key cache.novavero.ai-1:9gQ7tLWMM+2tdC9H5sKMJltDIPfD7X2GWlZe8Aa8hHQ=
...
C:\nix\store\<hash>-hello
> C:\nix\store\<hash>-hello\bin\hello.exe
Hello, world!

The cache holds this closure as CI last built it from main, so the build downloads what the cache holds and builds only what it lacks. Without a substituter it fetches the pinned toolchain packages and builds the toolchain before Hello.

On Windows

The store is C:\nix\store by default. Derivations keep the /nix/store spelling that hashes are computed over, and it is mapped to the real directory only when a builder starts. A file's executable bit is kept in an NTFS alternate data stream. A store path therefore serializes to the same NAR, with the same hash, as it does on other platforms.

A path with a root but no drive, such as /src/default.nix, names that path on the store's drive, whichever drive is current: C: for the default store, or the drive of the directory --store names.

Library

nova-nix is also a Haskell library, documented on Hackage. Nix.Parser parses, Nix.Eval evaluates, and Nix.Store, Nix.Builder, Nix.Realise and Nix.Substituter keep the store, build and substitute. Evaluation needs the C data layer, so it runs between arenaInit and arenaDestroy, as Nix.Eval.Arena describes.

Building from source

You need this only to work on nova-nix itself, not to use a release. It needs GHC and cabal-install; tested-with in nova-nix.cabal names the GHC version CI uses.

git clone https://github.com/Novavero-AI/nova-nix.git
cd nova-nix
cabal update
cabal build
cabal test

Contributing

See CONTRIBUTING.md. Planned work is on the Nova roadmap project. Please report security issues privately through GitHub's vulnerability reporting rather than in a public issue.

License

Apache-2.0. See LICENSE and NOTICE.