trynix: Any Nix Package Running Right in Your Browser
Translated by a model; the original is in Russian.
Farid Zakaria, known for his experiments around the Nix ecosystem, calls his new project his magnum opus. trynix (trynix.dev) lets you open the entire history of nixpkgs in your browser — over 310,083 package versions — and run any of them in a virtual machine that boots right there in the tab. No servers: the page is made of static files, and everything else is pulled from public caches.
How it works
The author stitched together several of his earlier efforts. The nixpkgs-multiverse, grail and omniflake projects learned to index every version of every package and to skip the build step: instead of a lengthy expression evaluation, the service immediately requests the ready-made store path that Hydra once built. If the binary exists, you can run it.
The missing link was a runtime environment: store paths are ELF files for x86-64 or aarch64. The solution was a Linux kernel compiled to WebAssembly: a real x86_64 kernel loads in the browser, gets handed a filesystem holding a Nix store, and the paths it needs are fetched from the cache. The result is a full-fledged Nix client inside a tab — a Nix store in memory, a kernel on WebAssembly, and a terminal emulator on the page.
An amusing twist: five years ago Zakaria himself asked that cache.nixos.org serve the header access-control-allow-origin: * — back then for the sake of working with OpenAPI. Now it is precisely this CORS header that makes the whole trick possible. GitHub Pages and Cachix have it too, so you can run in the browser even a package that isn't in the public cache — all it takes is sharing a link to your own store path.
Making it all feel instant
Booting a kernel under emulation is slow, and without some cleverness no one would use the service. So trynix pre-fetches the engine and a VM snapshot, and never boots the machine from scratch — it is resumed from a snapshot taken the moment before the store is mounted. On repeat visits, all that's left is to pull the closure of the package you need.
It still doesn't become instant: the first run of a binary requires translating x86_64 into WebAssembly, while subsequent ones are faster thanks to caching. The closure size is limited by the tab's memory (around 1.5 GiB) and by WebAssembly's 32-bit addressing (a maximum of 4 GiB). The author found some of the optimizations with the help of language models.
More than just a fun trick
Zakaria sees practical value too. Reviewing a pull request turns into a click on a link that loads exactly the artifacts CI built — no cloning, no building. Bug reports can carry their own environment: “works on my machine” becomes a URL for reproduction. Documentation gains runnable examples with the tool's version pinned forever. And finally, archaeology: you can take Python from 2017 or hello from 2005 for a live spin.
The sources are available on GitHub. As the author notes, the open CORS header quietly waited for years to finally be “put to use.”
Source: Lobsters
Comments
Sign in, to comment.