grail

Version ranges for nixpkgs. Write constraints and a solver finds the revisions in 14 years of nixpkgs history where all of them hold. The page is a single-page application: the index, the solver, and the graph run entirely in your browser.

small one range one version medium python3 × openssl 1.1 two worlds an impossible ask big 6-way coexistence coherence two eras mixed forced to one era one everything impossibly incoherent

the grammar, in one table

@attach a version range; a bare attr means any version
>= > <= < =compare in builtins.compareVersions order
1.1.*component-wise prefix: 3.8 accepts 3.8.9, refuses 3.81
3.10..3.12inclusive interval, prefix-inclusive upper end
, / ||and / or
^coexistence: one shared revision serves the whole group

The solver is clingo compiled to WebAssembly, running grail's solve.lp unmodified against the nixpkgs-multiverse index. Everything is static files; nothing leaves your browser.