2026-10-03
Three new runtimes.
node-python is Node and Python in one image, so a job that edits with a Python script and builds
with npm stays in one sandbox. media adds ffmpeg and libvips. browser adds headless Chromium driven by Playwright,
with axe, importable with no install. All three are built in this repository for amd64 and arm64 and
tagged with the package version. See Images.shmSize. The size of /dev/shm, as a reusable capacity like memory. The browser runtime gets 512 MiB by
default (RUNTIME_DEFAULTS), because an engine’s 64 MB crashes Chromium.pull() and nsbx pull. Pull runtime images ahead of the first command — the browser image is too large to
pull inside one.A rebuild keeps the workspace. When create() rebuilds a sandbox because its shape no longer serves — another
image, more room, a tighter ceiling — it replaces the container and keeps the workspace, as lifetime retirement
already did. It used to delete the workspace too, so a job moving between images reinstalled its dependencies cold
on every switch. replace: true and remove() still delete it.2026-09-23
Sandboxes stop themselves. A sandbox’s main process was
sleep infinity, and the idle stop and
maximum lifetime ran on a timer in whichever process created it. When that process exited — a test,
a CLI, a server restarted by a deploy — nothing was left to stop the sandbox, and it stayed
running forever. A reclaimer that rightly never touches a running sandbox kept it too.The main process is now a small watchdog that exits when nothing has run for the idle timeout, and
at the lifetime plus the idle timeout regardless, so the deadlines hold with no process alive. A
command left running in the background counts as busy. It traps SIGTERM, so stop() is prompt.
Existing sandboxes keep sleep infinity until they are retired.Two new options: selfStop (default true; false restores sleep infinity) and housekeeping
(default true; false starts no sweep timer in this process).2026-09-21
A CLI.
npx nativesandbox run "node --version" works with nothing installed — there is no
binary to download and no runtime to version-match, because the container engine on your host
is the runtime.nsbx doctor checks whether a host can run sandboxes and explains what is wrong when it cannot,
including the one failure that reads as success: a cgroup limit the kernel accepts and
ignores. --deep creates a real sandbox and reads memory.max back to prove it. It exits
non-zero when the host is not ready, so it works as a deployment gate.nsbx setup applies what doctor found, printing each command and asking before it runs — it
installs system packages and edits systemd units, so it does not do that quietly. --print
shows them and changes nothing; --yes is for CI.run, exec, ls, rm and sweep cover the fleet from a terminal. run and exec stream
output as it is produced and exit with the command’s own status.Both binaries — nativesandbox and nsbx — ship in the same package. Still zero dependencies.2026-09-21
nativesandbox/package.json is now reachable through the exports map. Tools that read a
dependency’s manifest — a version gate, a bundler, a doctor script — hit
ERR_PACKAGE_PATH_NOT_EXPORTED on 0.1.0 and had to resolve some other subpath and walk up to
find the directory.2026-09-21
The first release.Sandboxes.
create() with meet-or-exceed reuse, so a dependency install survives between
commands instead of going cold. replace forces a fresh one. list(), remove() and
removeAll() are scoped by label, so a sweep can only ever touch its own.Commands. exec() through a shell, with live output through onFrame, timeouts that kill
forked grandchildren too, and AbortSignal cancellation reported separately from a timeout. A
non-zero exit resolves rather than throwing.Workspace. Bind-mounted rather than copied through an agent channel — 7× faster to place 200
files and 49× faster to read them back than a microVM runtime on the same machine. Traversal is
refused rather than normalised.Limits. Memory, CPU and PID ceilings through cgroups, and a per-sandbox network policy.
Sizes are a branded Mebibytes, so memory: 512 does not compile.Isolation. Every Linux capability dropped and no-new-privileges, both on by default and both
verified against a real npm install. An optional read-only root, and gVisor through
runtime: "runsc".Reclaiming. Idle stop and a hard maximum lifetime, settable per instance or per sandbox and
recorded on the container so they survive a restart. Neither interrupts a command in flight.