What trynix Actually Boots When You Open a Tab
Software / explainer
What trynix Actually Boots When You Open a Tab
A single developer's side project runs a full x86_64 Linux virtual machine, and 13 years of package history, inside a browser tab.
What trynix actually boots
trynix.dev, published on Sept. 4 by software engineer Farid Zakaria, is not a simulation of a Linux machine. It is a real Linux kernel, compiled to WebAssembly through a project called qemu-wasm, running inside a QEMU virtual machine that boots entirely inside a browser tab. Simon Willison, who wrote about the project on Sept. 10, describes it as a full x86_64 machine reachable at a URL, with no server executing your session once the page loads. The terminal you type into is Ghostty, a terminal emulator, rendered as part of the page rather than a screenshot of one.
Zakaria calls it his "magnum opus of Nix work," a reference to Nix, the package manager whose entire release history the project makes bootable. Point a browser at a URL like trynix.dev/?pkg=python3@3.6.2 and the page assembles a Linux machine, fetches that exact package build, and drops you into a shell running it, all without installing anything locally.
Why 13 years of package history works at all
Nix's binary cache, hosted at cache.nixos.org, is a plain HTTP file server, which means a browser can fetch package builds directly with no backend of trynix's own sitting in between, provided the server sends permissive cross-origin headers. Zakaria's post credits two supporting projects for making the whole history reachable: nixpkgs-multiverse, which indexes more than 310,083 package versions across the lifespan of nixpkgs, and omniflake, which aggregates more than 16,000 Nix flakes. A third project, grail, adds support for resolving version ranges rather than exact pins. Together they turn nixpkgs from a single current snapshot into an addressable archive, and trynix is the part that makes any entry in that archive bootable rather than merely browsable.
The package itself, once fetched, lives in an in-memory Nix store capped at roughly 1.5 gigabytes, close to the 4-gigabyte ceiling WebAssembly imposes on a single linear memory. That ceiling is why trynix boots a package plus its closure, the dependency tree required to run it, rather than a full desktop environment.
How fast it actually is
Zakaria published boot-to-shell timings for three packages, split between a first visit and a repeat visit after the browser has cached the machine snapshot:
| Package | First Visit | Revisit |
|---|---|---|
| Python 3 | 7.5 seconds | 3.5 seconds |
| ripgrep | 4.3 seconds | 1.7 seconds |
| GNU hello | 4.2 seconds | 1.5 seconds |
The gap between the two columns comes from two optimizations layered on top of the base emulator: pre-fetching the engine and package snapshot before the shell is needed, and resuming a saved virtual machine snapshot instead of running a cold boot each time. Demonstrated packages include three separate builds of GNU hello (2.10, 2.12.2 and 2.12.3), Python 3.6.2 from 2017, Python 2.7.18, ripgrep and pfetch, spanning package releases that predate trynix itself by close to a decade.
What it can't do
Zakaria is direct about the limits in his own post. There is "nothing graphical": the machine exposes a serial console, not a display, so anything requiring a GUI does not run. Binary execution is slow under emulation generally, and a package's first run inside a session costs more time still, because the machine has to translate x86_64 instructions to WebAssembly before executing them. The 1.5-gigabyte store ceiling also means a large closure, a package with many heavy dependencies, may not fit in a single session at all.
Those limits place trynix closer to a demo of an idea than a development environment: it is a fast way to confirm what an old binary actually did, or to hand someone a runnable link to a specific package version instead of a paragraph of installation instructions, rather than a place to do sustained work. It follows the same in-browser-WebAssembly playbook as two independent teams porting GNU Radio to run in a browser tab, treating the browser as a portable machine rather than a display for one running elsewhere.
For a project built by one person, hosted in part on GitHub Pages acting as a free binary cache with the right CORS headers set, running any of 310,083 package versions in a tab is already more history than most developers can reach with a locally installed package manager, and it costs Zakaria no server to keep it that way.
Sources
More in Software
- 01ZCode Uploads Users' Full Git History, Zhipu Says It Deletes ItA developer's reverse-engineering forced a same-day apology from Zhipu over a coding assistant that never told users it was packaging their repositories for the cloud.
- 02Alibaba's Open Code Review Tool Ships an IntelliJ PluginVersion 1.12.6 extends the AI code reviewer to JetBrains IDEs the same week Alibaba's own benchmark shows it trading recall for precision against Claude Code.
- 03Flet Reaches 1.0, Ships One Python App to Six PlatformsFeodor Fitsner's framework rebuilt its bridge to Flutter for the stable release, but has not said how many people pay for anything built on top of it.
- 04Bend 2 Bets Formal Proof Can Catch AI's Coding MistakesVictor Taelin's rewritten language backs its safety pitch with a compiler its own README calls 99 percent AI-written and not yet audited.