jinx Nix, transpiled to TypeScript

Comparisons

Where jinx sits among the other implementations of the Nix language.

Project Kind Language Checks drvPaths against Nix
jinx compiler to TypeScript TypeScript all of nixpkgs on three systems: 231,777 of 231,777
fix bytecode VM Zig all of nixpkgs on one system: 80,586 of 80,586
snix (ex tvix) bytecode VM Rust stdenv, hello, firefox, cross hello in CI
hnix tree-walking interpreter Haskell no claim
nix-eval-js tree-walking interpreter JavaScript no; self-rated 5% complete
Nix, Lix tree-walking interpreter C++ the reference

Every project in the table except jinx is an interpreter: Nix source in, value out. jinx is a compiler: Nix source in, a program out, which produces the value when run.

fix

fix evaluates nixpkgs' ci/eval/outpaths.nix with itself and with a reference Nix, and as of its 0.3.0 release every one of 80,586 attributes has an identical drvPath, including agreement on which attributes fail. It is fast: a minimal NixOS closure in 0.54 s against Nix's 2.25 s on the same machine, and the full nixpkgs universe in about 52 s and 34 GB with 32 threads, through a parallel VM with speculative forcing. Its documentation is the clearest account of derivation hashing outside the Nix source. jinx's parity run (verification.md) follows fix's method.

snix

snix, formerly tvix, has worked on nixpkgs compatibility since 2022 and defines correctness as jinx does: drvPath and outPath equal to Nix's. Its CI checks a fixed list (stdenv, hello, firefox, cross hello, a NixOS ISO) on every commit; no whole-nixpkgs number has been published. Its write-ups record what is hard: the undocumented ATerm subset and hash-modulo intermediates, derivation being Nix code around derivationStrict, string contexts that cannot be skipped because stdenv works around a Nix bug, tryEval under bytecode, and builtins.path coupling evaluator to store. jinx hit the same list.

hnix and the rest

hnix is a Haskell interpreter whose goal of evaluating all of nixpkgs has had open issues since 2020. nix-eval-js is a JavaScript tree-walker written for incremental evaluation inside an editor, rated 5% complete by its author. nix2c by the same author is a Nix-to-C transpiler labelled a failed experiment, on the argument that compiling a dynamic language still pays runtime type checks and still re-evaluates everything. The type checks do stay; a compiled module graph is, though, what incremental evaluation needs.

In the other direction, garn writes a flake from TypeScript and hands it to Nix, NiJS (2013) is a JavaScript DSL that writes Nix, and PureNix compiles PureScript to Nix. Nickel's Nix import links libnixexpr and evaluates eagerly. No Nix-to-JavaScript or Nix-to-TypeScript compiler existed before jinx.

Where jinx differs

What fix and snix have that jinx does not: years of hardening, a parallel evaluator in one process, and speed. jinx is 2.6x to 5.4x slower than Nix per attribute (performance.md).

Edit this page on GitHub