{"slug": "vroot-instant-daemonless-root-sandboxes-from-a-single-flag", "title": "Vroot – Instant, daemonless root sandboxes from a single flag", "summary": "A developer tool called vroot launches instant, daemonless Linux root sandboxes from a single command-line flag, using unprivileged user namespaces and bubblewrap to give agents and developers a real uid 0 shell with no daemon, image registry or sudo. vroot stores each environment as a single compressed image mounted copy-on-write, with typical cold starts in tens of milliseconds, and offers JSON output via commands such as `vroot build -python --json`, `vroot ls --json` and `vroot envs --json`, plus atomic cache extraction so concurrent launches cannot corrupt each other. The project publishes a machine-facing contract in docs/AGENTS.md and lets users checkpoint a sandbox with `vroot save NAME golden.vroot` and fork it into multiple named sandboxes.", "body_md": "**Instant, isolated, single-file Linux development environments that boot in milliseconds — built from a flag.**\n\n`vroot` gives you a **throwaway or persistent root filesystem** that starts in\nmilliseconds, is fully isolated from your host, and contains exactly the tools\nyou asked for:\n\n```\nvroot                      # banner + quick-start help\nvroot -base                # a root shell (blank Alpine Linux)\nvroot -python              # a root shell that has Python\nvroot -node -python        # compose flags freely\nvroot -sqlite -python db   # a persistent sandbox named \"db\"\nvroot -rust -- cargo build # run one command instead of opening a shell\n```\n\nNothing from your host is visible inside unless you expose it with `-v`, and\nthe sandbox disappears when you exit (unless you give it a name).\n\nIt is also the shortest path from an AI agent to a working toolchain: no\ndaemon, no image registry, no sudo, no build queue. See\n[docs/AGENTS.md](https://github.com/gairxx/vroot/blob/main/docs/AGENTS.md) for the machine-facing contract.\n\nAgents do not need a nicer terminal, they need **resources on demand and no\ncoordination overhead**. `vroot` is built for that shape of work:\n\n- **No daemon, no registry, no sudo.** A toolchain is one flag away and starts\nin tens of milliseconds, so an agent can afford to spawn a fresh environment\nper step instead of reusing a fragile one.\n- **JSON when you ask for it.**`vroot build -python --json` ,`vroot ls --json` ,`vroot envs --json` ,`vroot info NAME --json` — stdout is\npure JSON, logs stay on stderr, exit codes are meaningful.\n- **Parallel-safe.** N agents asking for the same environment produce one\nimage: the first builds, the rest wait and report`\"cached\": true` . Cache\nextraction is atomic, so concurrent launches cannot corrupt each other.\n- **Checkpoint, then fork.**`vroot save NAME golden.vroot` turns a good state\ninto one file; boot it as many named sandboxes as you like and throw the\nfailed ones away. The image is never modified.\n- **Host stays hidden.** Real uid 0 inside, but no host filesystem, no host\nprocesses, no host network surprises unless explicitly mounted.\n- **Deterministic surface.** Anonymous sandboxes are ephemeral, named ones\npersist,`-offline` cuts the network, and`vroot doctor` is an explicit\npreflight.\n\n``` bash\n$ vroot build -python --json\n{\"env\":\"/home/u/.local/share/vroot/envs/python-84d0423ed3.sqfs\",\"cached\":false}\n$ vroot -python task1 -- pytest -q            # exit code is pytest's\n$ vroot save task1 task1.vroot && vroot task1.vroot retry -- pytest -q\n```\n\nThe full contract (output shapes, locking, fork semantics, rules for agents)\nlives in [docs/AGENTS.md](https://github.com/gairxx/vroot/blob/main/docs/AGENTS.md).\n\n`vroot` is a lightweight sandbox and container alternative for the common case\nwhere you just want a **clean, disposable Linux shell with some language or\ntool installed** — without images to build, a daemon to run, or a slow boot.\n\n- **Instant.** Environments are stored as single compressed images and mounted\ncopy-on-write. Starting a shell is a`mount` +`exec` , not a container boot.\nTypical cold start is tens of milliseconds.\n- **Isolated.** Your real`$HOME` , files and processes are not visible by\ndefault. The sandbox has its own root, PID namespace, hostname and network\n(disable networking with`-offline` ).\n- **Real root, no sudo.** Inside you are`uid 0` with full capabilities, using\nunprivileged user namespaces and bubblewrap. No daemon, no setuid helper, no\nroot on the host.\n- **Composable.**`-php -sqlite -git` builds one environment containing all\nthree. Every distinct combination is cached separately and reused.\n- **Single file.** Build once, then`save` a sandbox — including your changes —\ninto one portable`.vroot` image you can boot anywhere, and register as a\nreal file type on your desktop with`vroot filetype install` .\n- **Extensible.** Every flag is a small text recipe. Add your own language or\ntool in a few lines — see[docs/BUILDING.md](https://github.com/gairxx/vroot/blob/main/docs/BUILDING.md) .\n\n|  | **vroot** | Docker / Podman | chroot | proot | full VM | \n|---|---|---|---|---|---|\n| Boot time | ~10–50 ms | ~0.3–2 s | instant | ~0.1–1 s | seconds | \n| Requires root / daemon | **no / no** | no / yes (or rootless setup) | **yes** | no | no | \n| Host filesystem hidden | **yes** | yes | no | partial | yes | \n| Real `uid 0` inside | **yes** | yes | yes | no (faked) | yes | \n| Storage per environment | **one file** | layered image + container | directory | directory | disk image | \n| Compose tools by flag | **yes** | Dockerfile / run args | manual | manual | manual | \n| Best for | root shells, language sandboxes, reproducible dev shells | services, images, orchestration | legacy sysadmin | emulation, odd arches | full isolation | \n\n- **Linux** with unprivileged user namespaces enabled (default on modern\ndistros; check with`vroot doctor` ).\n- `bubblewrap` ,`util-linux` (`unshare` ),`squashfs-tools` (`mksquashfs` ,`unsquashfs` ).\n- `curl` or`wget` — only for the first build (to fetch the base rootfs).\n- `docker` — only if you use a flag whose recipe targets the Debian base\n(`bun` ,`clojure` ,`groovy` ,`julia` ,`kotlin` ,`scala` ,`swift` ).\n\n```\nsudo apt install bubblewrap util-linux squashfs-tools curl\nsudo dnf install bubblewrap util-linux squashfs-tools curl\nsudo pacman -S bubblewrap util-linux squashfs-tools curl\n```\n\nThen verify your host:\n\n```\nvroot doctor\n```\n\nOne line, no sudo, no daemon:\n\n```\ncurl -fsSL https://raw.githubusercontent.com/gairxx/vroot/main/install.sh | sh\n```\n\nThat installs the launcher to `~/.local/bin/vroot` and the recipe catalogue to\n`~/.local/lib/vroot`. Then check the host and start a shell:\n\n```\nvroot doctor      # verify bubblewrap, namespaces, squashfs\nvroot -python     # a root shell with Python\n```\n\nPrefer clicking? **[gairxx.github.io/vroot](https://gairxx.github.io/vroot/)**\nhas copy buttons for every method.\n\n| Method | Command | \n|---|---|\n| One-line install | `curl -fsSL https://raw.githubusercontent.com/gairxx/vroot/main/install.sh \\| sh` | \n| Clone and install | `git clone https://github.com/gairxx/vroot && cd vroot && sh install.sh` | \n| Source archive | [main.tar.gz](https://github.com/gairxx/vroot/archive/refs/heads/main.tar.gz) → unpack →`sh install.sh` | \n| Custom prefix | `curl -fsSL ... \\| sh -s -- --prefix /opt/vroot` | \n| Pin a ref | `curl -fsSL ... \\| sh -s -- --version <branch-or-tag>` | \n| Uninstall | `curl -fsSL ... \\| sh -s -- --uninstall` | \n\n`install.sh` installs from the working tree when run inside a checkout, and\notherwise downloads a tarball — no build step either way. Uninstalling keeps your\nsandboxes and images in `~/.local/share/vroot`.\n\n```\n# Banner + quick-start help (no sandbox)\nvroot\n\n# A disposable root shell (blank Alpine)\nvroot -base\n\n# A root shell with a language\nvroot -python\nvroot -node\nvroot -rust\n\n# Compose as many tools as you like\nvroot -php -sqlite -git\n\n# Run a single command and exit\nvroot -node -- node -e 'console.log(process.version)'\n\n# A persistent sandbox you can come back to\nvroot -python work\nvroot work -- python3 -c 'print(\"still here\")'\n\n# Expose a host directory (read-write), keep everything else hidden\nvroot -go -v ~/src:/src -- sh -c 'cd /src && go test ./...'\n\n# Fully offline\nvroot -python -offline\n```\n\nEverything is root inside, but your host is untouched:\n\n``` bash\n$ vroot -python -- sh -c 'id; hostname; ls /home'\nuid=0(root) gid=0(root)\nvroot\nls: /home: No such file or directory\n```\n\nOne flag per tool or language. Combine them to build exactly the environment you need.\n\n| `-python` | `-node` | `-deno` | `-bun` | \n| `-php` | `-ruby` | `-perl` | `-lua` | \n| `-r` | `-julia` | `-go` | `-rust` | \n| `-zig` | `-nim` | `-crystal` | `-d` | \n| `-swift` | `-haskell` | `-elixir` | `-erlang` | \n| `-ocaml` | `-clojure` | `-groovy` | `-java` | \n| `-kotlin` | `-scala` | `-dotnet` | `-fsharp` | \n| `-gcc` | `-clang` | `-cmake` | `-gfortran` | \n| `-nasm` | `-sqlite` | `-postgres` | `-mysql` | \n| `-git` | `-openssh` | `-curl` | `-vim` | \n| `-base` | `-debian` |  |  | \n\nFlags answer to aliases too (`-python3`, `-nodejs`, `-cargo`, `-golang`, ...).\nSee the full catalog with details in [docs/LANGUAGES.md](https://github.com/gairxx/vroot/blob/main/docs/LANGUAGES.md) or:\n\n```\nvroot recipe list\nvroot [FLAGS] [NAME] [OPTIONS] [-- COMMAND]\n```\n\n| Option | Meaning | \n|---|---|\n| `-v SRC[:DST][:ro]` | expose a host path (read-write, or read-only with `:ro` ) | \n| `-offline` | no network (loopback only) | \n| `-cwd DIR` | working directory (default `/root` ) | \n| `-env K=V` | set an environment variable | \n| `-name NAME` | persistent sandbox name | \n| `-hostname H` | hostname inside (default: the sandbox name) | \n| `-clean` | start with an empty environment | \n| `-rm` | delete the sandbox after this session | \n| `--json` | machine-readable output for `build` ,`ls` ,`envs` ,`info` | \n\n| Command | Meaning | \n|---|---|\n| `vroot ls` | list sandboxes | \n| `vroot rm NAME... \\| --all` | delete sandboxes | \n| `vroot info NAME` | sandbox details | \n| `vroot save NAME [OUT.vroot]` | pack a sandbox into one `.vroot` image file | \n| `vroot OUT.vroot` | boot from a saved image file | \n| `vroot filetype install` | register the `.vroot` image file type with the OS | \n| `vroot envs` | list built environment images | \n| `vroot prune` | clear caches and temporary files | \n| `vroot recipe list\\|show\\|new\\|edit\\|path` | work with recipes | \n| `vroot doctor` | check the host setup | \n\n1. **Resolve.** Flags are looked up in recipes; matching recipes are merged\n(packages, setup steps, environment,`PATH` , verification).\n2. **Build once.** A single environment image (`envs/<flags>-<hash>.sqfs` ) is\nbuilt the first time a combination is used: a minimal base rootfs — Alpine,\nor Debian when a recipe needs glibc — is populated inside a sandbox and\npacked with`mksquashfs` .\n3. **Launch.** Each session caches/unpacks the image and starts it through an**overlayfs** mount plus**bubblewrap** , giving you a root shell with full\ncapabilities, isolated namespaces and copy-on-write writes.\n\nPersistent sandboxes keep their changed files in\n`~/.local/share/vroot/instances/<name>/upper`, so `save` can pack the exact\nstate back into a portable single-file image.\n\n```\n                 ┌──────────── envs/python+sqlite-<hash>.sqfs ────────────┐\n                 │  read-only squashfs image (built once, cached)         │\n                 └───────────────────────┬───────────────────────────────┘\n                                         │ unsquashfs\n                     lowerdir ───────────┤\n                                         ▼\n  host $HOME ── overlayfs (COW) ──► merged root ── bubblewrap ──► uid 0 shell\n  (hidden)         upperdir (your writes)        namespaces: user, pid,\n                                                   uts, ipc, net, mount\n```\n\nEvery flag is a small recipe. Adding a language or tool usually takes a few lines:\n\n```\nname = mytool\nprovides = mytool\nbase = alpine\npackages = mytool\nverify = mytool --version\ndescription = My tool\nvroot recipe new mytool     # create + edit, then:\nvroot -mytool\n```\n\nSee [docs/BUILDING.md](https://github.com/gairxx/vroot/blob/main/docs/BUILDING.md) for worked examples, and\n[docs/RECIPES.md](https://github.com/gairxx/vroot/blob/main/docs/RECIPES.md) for the field reference.\n\n- [docs/AGENTS.md](https://github.com/gairxx/vroot/blob/main/docs/AGENTS.md) — the contract for AI agents and automation\n- [docs/BUILDING.md](https://github.com/gairxx/vroot/blob/main/docs/BUILDING.md) — add your own language/tool\n- [docs/LANGUAGES.md](https://github.com/gairxx/vroot/blob/main/docs/LANGUAGES.md) — full flag catalog\n- [docs/RECIPES.md](https://github.com/gairxx/vroot/blob/main/docs/RECIPES.md) — recipe field reference\n- [examples/](https://github.com/gairxx/vroot/blob/main/examples) — example recipes\n\n**Is this Docker?**\nNo. Docker builds and runs OCI images via a daemon and is great for services and\norchestration. `vroot` is a single script that gives you an isolated root shell\nfrom a single-file, copy-on-write image — no daemon, no image build, near-instant\nstartup. It is closer to `proot` or a beefed-up `chroot`.\n\n**Do I need root or sudo?**\nNo. Everything runs through unprivileged user namespaces and bubblewrap.\n\n**Is it safe? Do I really get root?**\nInside the sandbox you are `uid 0` with full capabilities, but you are confined\nby user, PID, mount, UTS and IPC namespaces, and by default the host filesystem\nis not visible. It is real root in an isolated namespace, not root on your host.\n\n**Can I access my project files?**\nYes, explicitly, with `-v ~/src:/src`. Nothing is shared until you ask.\n\n**Where are environments stored?**\nUnder `~/.local/share/vroot/` (`envs/`, `cache/`, `instances/`). Override\nwith `$VROOT_HOME`. Recipes are read from\n`~/.config/vroot/recipes/` (override with `$VROOT_CONFIG`).\n\n**How do I make a portable environment?**\n`vroot save NAME out.vroot` writes a single image file; boot it with\n`vroot out.vroot`. Images are squashfs under the hood and also work with a\n`.sqfs` extension.\n\n**Can my file manager recognise vroot images?**\nYes. Run `vroot filetype install` once. It registers a custom\n`application/x-vroot-image` MIME type (globs `*.vroot` / `*.sqfs`, plus\ndetection by squashfs magic) and a desktop handler, so images show a distinct\ntype and open with `vroot`. Undo with `vroot filetype uninstall`;\n`vroot filetype status` shows what is installed.\n\n**Why Alpine by default?**\nAlpine images are tiny and build in seconds. Recipes that need glibc or\n`apt`-only packages opt into a Debian base automatically.\n\n**Does it work without systemd / in a container / under WSL?**\nIt needs unprivileged user namespaces. Run `vroot doctor` to check.\n\n**Can an AI agent use it?**\nYes, that is a first-class use case. Management commands take `--json`, stdout\nis pure JSON, exit codes are forwarded from the command you run, builds of the\nsame environment are serialised across parallel processes, and a sandbox can be\ncheckpointed with `save` and forked by booting the image file under new names.\nSee [docs/AGENTS.md](https://github.com/gairxx/vroot/blob/main/docs/AGENTS.md).\n\nroot shell sandbox · unprivileged Linux sandbox · container alternative · lighter than Docker · Docker alternative for shells · proot alternative · chroot alternative · bubblewrap sandbox · user namespace sandbox · rootless sandbox · run as root without sudo · isolated development shell · ephemeral root shell · persistent dev environment · single-file environment · squashfs environment image · overlayfs copy-on-write · instant Linux sandbox · fast sandbox boot · language sandbox · Python sandbox · Node.js sandbox · Rust sandbox · PHP sandbox · Go sandbox · polyglot dev environment · reproducible development environment · disposable shell · dev container alternative · sandbox for AI agents · agent sandbox · LLM tool sandbox · autonomous agent environment · machine-readable sandbox · parallel agent sandboxes · checkpoint and fork sandbox · JSON CLI sandbox · coding agent runtime.\n\n[MIT](https://github.com/gairxx/vroot/blob/main/LICENSE) © 2026 gairxx", "url": "https://wpnews.pro/news/vroot-instant-daemonless-root-sandboxes-from-a-single-flag", "canonical_source": "https://github.com/gairxx/vroot/tree/main", "published_at": "2026-11-01 03:51:53+00:00", "updated_at": "2026-11-01 04:21:10.456550+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools"], "entities": ["vroot", "Alpine Linux", "bubblewrap"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/vroot-instant-daemonless-root-sandboxes-from-a-single-flag", "markdown": "https://wpnews.pro/news/vroot-instant-daemonless-root-sandboxes-from-a-single-flag.md", "text": "https://wpnews.pro/news/vroot-instant-daemonless-root-sandboxes-from-a-single-flag.txt", "jsonld": "https://wpnews.pro/news/vroot-instant-daemonless-root-sandboxes-from-a-single-flag.jsonld"}}