Getting started with Silo in three commands
Install silo from the Homebrew tap, add its shims to your PATH, and install your first sandboxed tool. Total setup time: one coffee's worth.
Silo ships as a Homebrew tap. The first install takes about five minutes — most of that is the one-time runtime bootstrap (kernel download, Swift toolchain, vminitd cross-compile). Everything after is seconds.
Prerequisites
- Apple Silicon Mac (M1 or later)
- macOS 26 (Tahoe) or later — Silo uses Apple’s Containerization framework, which is macOS 26+
- Homebrew
- Apple’s
containerCLI:brew install container
The Homebrew formula installs a codesigned binary with com.apple.security.virtualization entitlements. (If you prefer to build from source, clone the repo and run make install — do not use raw go build, macOS will SIGKILL an unsigned binary.)
Install
brew install rchekalov/silo/silo
# Put silo shims on your PATH (same convention as `brew shellenv`)
echo 'eval "$(silo shellenv)"' >> ~/.zshrc
source ~/.zshrc
The three-part name (user/tap/formula) is intentional. There’s already a silo cask in homebrew/cask for an unrelated app; the fully-qualified form forces Homebrew to use our tap’s formula instead of the collision.
Verify:
silo --version
silo doctor
silo doctor reports runtime readiness. On a fresh machine it’ll say the kernel and initfs haven’t been fetched yet — that’s normal. They’ll be fetched by the first silo install.
Install your first tool
Pick a tool from the registry — Python is the gentlest:
silo install python
The first time you run this, Silo bootstraps the runtime: downloads a Kata Containers Linux kernel (~280 MB), installs Swift 6.3 via swiftly, cross-compiles vminitd for Linux, and produces an initfs.ext4 to boot the guest. All of this is cached at ~/.silo/ and reused forever after.
After bootstrap, it pulls the python:3.12-slim OCI image, unpacks it to an ext4 rootfs, and caches it. The next silo run python uses APFS clonefile to copy the cached rootfs in about a millisecond.
Run a command
Before the first example, the mental model in one sentence: every silo run is a fresh VM, and three things — and only three — persist across runs. Files you write into the mounted project directory (node_modules/, .venv/, build output). Registry-declared cache mounts (pip downloads, npm cache, cargo registry). And anything you bake into the rootfs with silo build. Everything else inside the VM vanishes when the command exits.
Because ~/.silo/bin/ is on your PATH, the shim for python transparently routes through Silo:
python --version
python -c 'import os; print(list(os.environ))'
That second command is the fun one: notice how much of your environment isn’t there. That’s the point.
To run explicitly without the shim:
silo run python -- script.py
silo shell python # interactive shell inside the VM
Tool-shorthand also works — silo python script.py expands to silo run python -- script.py, and silo npm test resolves the npm shim and routes to the node tool.
Give it a project
Create a .siloconf in your project root to tell Silo what this project needs:
# .siloconf
passEnv:
- GITHUB_TOKEN
overrides:
python:
network:
hostAccess: true
proxy:
allow:
- pypi.org
- "*.pythonhosted.org"
ports:
- host: 8000
guest: 8000
Or have Silo guess:
silo init
silo init scans for marker files (package.json, requirements.txt, Cargo.toml, etc.) and generates a .siloconf interactively.
Persist dependencies
A fresh VM per invocation means installed packages vanish at the end of each run. To persist them, use silo build:
silo build python -- pip install -r requirements.txt
That runs pip install inside the VM, captures the resulting filesystem as .silo/python/rootfs.ext4, and uses it as the starting point for future runs. Commit .siloconf, ignore .silo/, and your team gets reproducible builds.
Where to go next
- The case for sandboxing dev tools — why this project exists
- How Silo works — the cgo + Swift + Apple Containerization stack
- v0.4.0 release notes — what just shipped
Questions, issues, requests — open an issue on GitHub.
← all posts