Two things a dispatch on 2026-09-02 exposed. `macos-13` is being retired and the x86_64-apple-darwin job sat queued indefinitely waiting for a runner, while the other three targets built and smoke-tested in under three minutes. A release should not have that as a dependency, so Intel macOS is now cross-compiled from the arm64 runner. The cost is real and is stated rather than hidden: an x86_64 binary cannot be executed on an arm64 runner without Rosetta, which these images do not carry, so it is the one target whose smoke test cannot run. The matrix carries an explicit `smoke` flag, the step is gated on it, and the generated release notes say which binary is unexercised. Fabricating a pass for it would have been easy and worse. And a tag now produces a **draft** release rather than a published one. The binaries get attached and the notes get written, then a person reads both and presses publish -- which is the only step in this pipeline that cannot be undone in public. For the record, from the successful three: the musl smoke test measured the network from inside the static binary -- `up=1635Mbps rtt=2ms bloat=+0ms grade=A` -- so `ring` and the platform verifier do resolve root certificates in a fully static build. That was the one thing about this release nobody could have known without running it.
Run your games on a GPU you don't own — or one you do. Nestri puts an interactive workload in a hardware-accelerated virtual machine and streams it to you over QUIC, at a latency that lets you play rather than watch.
Note
This repository is mid-rewrite, and the documentation is behind the code. The guest-side components arrived recently and their docs are thin. Nothing here is stable yet: expect directories to move and interfaces to change. Proper documentation is on the way — issues and questions are welcome in the meantime, and are genuinely useful for deciding what to write first.
What is here
Two halves that meet over the network and share very little else.
The control plane — TypeScript, on Cloudflare Workers
apps/api |
The public REST API. Identity, teams, machines, games, pairing. |
apps/auth |
A self-hosted OpenAuth issuer — Steam and SSH-key login. |
packages/core |
The domain: every table, every operation, no HTTP. |
packages/auth |
Shared auth types and subjects. |
Postgres for state, Alchemy for infrastructure. See
docs/alchemy.md.
The guest — Rust, inside the box
These run inside a virtual machine, beside the game. None of them talk to the control plane.
apps/nescope |
A headless Wayland compositor for one fullscreen client. A lighter answer to the same problem gamescope solves. |
apps/nescapture |
A Vulkan implicit layer. It captures frames from inside the workload's own process and encodes them on the GPU that drew them — no copy out to the CPU and back. |
apps/neswire |
Audio capture and transport. |
apps/neshub |
One connection out of the box. Muxes video, audio, cursor and input into a single QUIC stream to the client. |
crates/nesprotocol |
The wire types they all share, so no two ends can drift apart silently. |
The hypervisor these run under is nesbox,
a separate repository: a micro-VM with a real GPU in it, using virtio-gpu native
context rather than passthrough, so one card can host several boxes at once.
Why a virtual machine
A container shares the host kernel, which makes strong isolation hard and a GPU harder. A micro-VM boots in about as long, isolates properly, and — with native context — gets close to bare-metal graphics. That choice is what makes "many sandboxes, one GPU" possible instead of one tenant per card.
Getting started
bun install
bun dev # control plane, local Cloudflare runtime
cargo build --workspace # guest components
cargo test --workspace
The Rust components expect a Linux host with a Wayland-capable GPU stack. They are not much use on their own yet — they are pieces of a box, and the thing that assembles a box is not open yet.
Status
Working: the API, auth, the domain model, and the guest components listed above.
Not here yet: the box lifecycle, storage, the edge, and the client. Some of that will open as it is written; some is deliberately closed. What decides which is whether it handles your data — that half is open on principle — or decides our capacity, which is the part we sell.
Contributing
Early, and the ground moves. The most useful contribution right now is telling us where the documentation failed you. Conventional commits; explain why in the body.