CLI reference
The heyvm binary launches the TUI when no subcommand is given and --api is not passed. With a subcommand, it runs that command and exits (pure CLI). With --api, it runs only the API server.
Global options
--api— Run only the HTTP API server (no TUI). Default port 3000; use--portto override.--port <PORT>— API server port when using--api(default: 3000). When running with TUI, API and TUI use port 34099.--msb-host <HOST>— Microsandbox server host (default: localhost).--dev— Development mode: TUI/CLI uses localhost for auth (default: https://auth.heyo.computer).--cloud-url <URL>— Cloud server URL.--auth-url <URL>— Auth server URL.--debug— Enable verbose logging.--upgrade— Self-upgrade to the latest version.
Sandbox types
Used with --type on create and other commands:
shellpython(alias:py)node(aliases:nodejs,javascript,js)
Backend types
Used with --backend-type:
msb— Microsandboxwasix— WASIXwasip2(aliases:wasi-p2,wasi_p2) — WASI Preview 2apple_container(aliases:apple-container,apple_vf,apple-vf) — Apple Container (macOS only)apple_virt(alias:apple-virt) — Apple Virtualization native VM (macOS only)bubblewrap— Bubblewrap namespace isolation (Linux only)sandbox_exec(alias:sandbox-exec) — macOS sandbox (macOS only)libvirt— Libvirt/KVM (Linux only)docker— Docker containerfirecracker— Firecracker microVMs (Linux only)
Subcommands
These run without starting the HTTP server. Sandbox identifiers can be id or slug where applicable.
create
Create a sandbox.
heyvm create --name my-sandbox \
[--image microsandbox/python] \
[--slug my-slug] \
[--type shell|python|node] \
[--mount HOST_PATH:SANDBOX_PATH ...] \
[--ttl-seconds 3600] \
[--start-command CMD] \
[--backend-type msb|apple_container|apple_virt|bubblewrap|libvirt|firecracker|...] \
[--env KEY=VALUE ...] \
[--setup-hook CMD ...]| Flag | Description |
|---|---|
--name <NAME> | Sandbox name (required) |
--image <IMAGE> | Container image (uses default from settings if omitted) |
--slug <SLUG> | URL-safe slug (default: slugified name) |
--type <TYPE> | Sandbox type: shell, python, or node |
--mount <MOUNT> | Mount as HOST_PATH:SANDBOX_PATH (repeatable) |
--ttl-seconds <TTL> | Time-to-live in seconds |
--start-command <CMD> | Start command for the sandbox |
--backend-type <BACKEND> | Backend to use (see Backend types) |
--env <KEY=VALUE> | Environment variable as KEY=VALUE (repeatable) |
--setup-hook <CMD> | Shell command to run after creation or mount replacement (repeatable) |
list
List running sandboxes.
heyvm listlist-inactive
List inactive (stopped) sandboxes.
heyvm list-inactive [--count 10] [--cursor ID] [--slug FILTER]| Flag | Description |
|---|---|
--count <COUNT> | Max number to return (default: 10) |
--cursor <CURSOR> | Cursor for pagination |
--slug <SLUG> | Filter by slug |
stop / restart / start
Stop, restart, or start a sandbox.
heyvm stop <id-or-slug>
heyvm restart <id-or-slug>
heyvm start <id-or-slug>exec
Execute a command in a sandbox.
heyvm exec <id-or-slug> -- COMMAND [ARGS...]
# Example:
heyvm exec my-slug -- python -c "print(1)"sh
Start an interactive shell in a sandbox.
heyvm sh <id-or-slug>mount-add
Add a mount to a sandbox.
heyvm mount-add --id <id-or-slug> --host-path /path/on/host --sandbox-path /path/in/sandbox [--read-only]| Flag | Description |
|---|---|
-i, --id <ID> | Sandbox ID or slug (required) |
--host-path <PATH> | Path on the host (required) |
--sandbox-path <PATH> | Path inside the sandbox (required) |
--read-only | Mount as read-only (default: false) |
bind
Bind a sandbox port to a public hostname. Requires the API_HOSTNAME environment variable to be set.
export API_HOSTNAME=example.com
heyvm bind <id-or-slug> <PORT>run-host
Run a host CLI command in the directory backing a sandbox mount. Useful for running tools that aren't installed in the sandbox but need to operate on the sandbox's files.
heyvm run-host <id-or-slug> -- COMMAND [ARGS...]
# Example:
heyvm run-host my-sandbox -- npm install| Flag | Description |
|---|---|
--mount-path <PATH> | Sandbox mount path to resolve (default: /workspace) |
--print-path | Print the resolved host path and exit |
wt
Create a git worktree sandbox and launch a shell in it. Pairs a branch
with a sandbox whose /workspace is the worktree directory. See the
worktree sandboxes guide for the
full workflow including detach, reattach, and cloud deploy.
# Create + attach (VM dies when the shell exits)
heyvm wt feat/cool-feature -b
# Create + background (VM persists; attach later with --shell)
heyvm wt feat/cool-feature --detach
# Attach to an existing wt sandbox
heyvm wt feat/cool-feature --shell
# List wt-* sandboxes only
heyvm wt --list
# Deploy the worktree to a cloud sandbox
heyvm wt feat/cool-feature --deploy
heyvm wt feat/cool-feature --deploy --publish-image --deploy-dockerfile ./Dockerfile| Flag | Description |
|---|---|
--backend-type, --backend <BACKEND> | Backend to use (default: platform default; apple_virt on macOS) |
--image <IMAGE> | Base image for the local sandbox |
--path <PATH> | Worktree path (default: ../{slugified-branch} relative to repo root) |
-b, --create-branch | Create new branch from HEAD if it doesn't exist |
-d, --detach, --no-shell | Create + return without attaching. Requires apple_virt on macOS (owner process keeps VM alive) |
--list | List existing worktree sandboxes; branch optional |
--shell | Attach to an existing worktree sandbox (no create) |
--deploy | Deploy the worktree to a cloud sandbox |
--deploy-driver <DRIVER> | Cloud driver: libvirt (default) / firecracker / kvm |
--deploy-image <IMAGE> | Cloud base image (default: ubuntu:24.04 for libvirt) |
--deploy-region <REGION> | Cloud region (default: US) |
--deploy-ttl-seconds <N> | Cloud sandbox TTL |
--deploy-port <PORT> | Public port to expose (repeatable) |
--publish-image | Build + publish an amd64 firecracker image from --deploy-dockerfile, then deploy using it |
--deploy-dockerfile <PATH> | Dockerfile for --publish-image |
--deploy-image-size-mb <N> | Rootfs size for the published image (default: 4096) |
--deploy-image-name <NAME> | Friendly name for the published image |
pull
Pull a Docker image for use with the apple_container backend.
heyvm pull <IMAGE> [--force]
# Example:
heyvm pull ubuntu:24.04
heyvm pull python:3.11-slim --forceimages-list
List pulled Docker images.
heyvm images-listimages build
Build a custom sandbox rootfs image from a Dockerfile. Today supports
--backend-type apple_virt; for firecracker see heyvm mvm build or
heyvm wt --deploy --publish-image.
heyvm images build --backend-type apple_virt \
--file ./Dockerfile \
--name my-image \
[--context DIR] \
[--size-mb 4096]| Flag | Description |
|---|---|
--backend-type <BACKEND> | apple_virt (macOS). Required. |
-f, --file <PATH> | Dockerfile path (default: ./Dockerfile) |
--context <DIR> | Build context (default: the Dockerfile's directory) |
-n, --name <NAME> | Image name. Output lands at ~/.heyo/images/apple_virt/<name>/ |
--size-mb <N> | Rootfs size (default: 4096) |
Requires Docker Desktop. After build: heyvm wt <branch> --image <name>
or heyvm create --backend apple_virt --image <name>.
logs
Tail a sandbox's owner log. Today only apple_virt sandboxes started
with --detach have one (the owner process writes
~/.heyo/sandboxes/<id>/owner.log).
heyvm logs <id-or-slug> [-n LINES] [-f]
# Example:
heyvm logs sb-abc12345 -f| Flag | Description |
|---|---|
-n, --lines <N> | Trailing lines to print before follow (default: 100) |
-f, --follow | Follow mode (like tail -f); Ctrl-C to exit |
archive
Archive sandbox mounts to the Heyo server (persists to S3).
heyvm archive <id-or-slug> [--token <TOKEN>] [--name <NAME>]| Flag | Description |
|---|---|
--token <TOKEN> | JWT token (or set HEYO_ARCHIVE_TOKEN env var) |
--name <NAME> | Optional name for the archive |
normalize-wasix-images
Normalize persisted WASIX sandbox image values.
heyvm normalize-wasix-images [--dry-run] [--to <IMAGE>]| Flag | Description |
|---|---|
--dry-run | Show planned changes without writing |
--to <IMAGE> | Replacement image/package to use |
archive-dir
Create an archive from a local directory (without needing an existing sandbox).
heyvm archive-dir [PATH] [--name <NAME>] [--mount-path <PATH>] [--no-ignore]
# Example:
heyvm archive-dir ./my-project --name v1| Flag | Description |
|---|---|
[PATH] | Path to the local directory (default: current directory) |
--name <NAME> | Optional name for the archive |
--mount-path <PATH> | Mount path prefix in the archive (default: /workspace) |
--token <TOKEN> | JWT token (or set HEYO_ARCHIVE_TOKEN env var) |
--no-ignore | Capture all files including build assets (node_modules, target, dist, etc.) |
mount
Mount a deployed sandbox workspace locally via SSHFS.
heyvm mount <id-or-slug> [--mount-path <PATH>] [--local-path <PATH>] [-- COMMAND ARGS...]
# Example:
heyvm mount my-deployed-app
heyvm mount my-deployed-app -- code .| Flag | Description |
|---|---|
--mount-path <PATH> | Remote path to mount via SSHFS (default: /workspace) |
--local-path <PATH> | Local directory to mount into (default: auto-generated temp dir) |
[COMMAND] | Host command to run after mounting (use -- before command). When omitted, mounts and waits for Ctrl+C. |
update
Replace a deployed sandbox's mount contents from an archive.
heyvm update <id-or-slug> --archive <ARCHIVE_ID> [--mount-path <PATH>]
# Example:
heyvm update my-deployed-app --archive abc123| Flag | Description |
|---|---|
--archive <ARCHIVE_ID> | Archive ID to replace the mount with (required) |
--mount-path <PATH> | Mount path to replace (default: /workspace) |
resize
Resize a deployed sandbox to a different size class.
heyvm resize <id-or-slug> --size-class <CLASS>| Flag | Description |
|---|---|
--size-class <CLASS> | Target size class (required): micro, mini, small, medium, large |
Size classes:
| Class | CPU | RAM |
|---|---|---|
micro | 0.25 | 512 MB |
mini | 0.5 | 1 GB |
small | 1 | 2 GB |
medium | 2 | 4 GB |
large | 4 | 8 GB |
proxy / connect / share / ssh
Expose local ports over P2P, connect to remote services, and share sandbox shells. See Local Tunnels & Proxies.
test-proxy
End-to-end proxy test: creates a VM, starts an HTTP server, binds a port, and verifies connectivity. Linux only (requires libvirt backend).
heyvm test-proxy [--keep]
Pass --keep to leave the sandbox running after the test.
install-skills
Download and install Claude Code skills into the current project. Skills provide Claude Code with knowledge of heyvm commands and deployment workflows.
heyvm install-skills [--path <PATH>] [--base-url <URL>]| Flag | Description |
|---|---|
--path <PATH> | Target directory (default: .claude/skills in current directory) |
--base-url <URL> | S3 base URL for downloads (default: heyo-cli-releases bucket) |
After installation, Claude Code automatically detects the skills in .claude/skills/.
install-codex-plugin
Download and install the heyvm Codex plugin. The plugin bundles heyvm MCP server wiring plus Codex skills such as $heyvm-use and $heyvm-workspace.
heyvm install-codex-plugin [--path <PATH>] [--base-url <URL>]| Flag | Description |
|---|---|
--path <PATH> | Target plugin directory (default: $CODEX_HOME/plugins/cache/heyvm/heyvm/local) |
--base-url <URL> | S3 base URL for downloads (default: heyo-cli-releases bucket) |
After installation, restart Codex. Codex does not currently expose a non-interactive plugin install subcommand, so the installer writes the plugin cache and enables heyvm@heyvm in ~/.codex/config.toml directly. The bundled heyvm --mcp server and skills load automatically on the next Codex startup.
Environment variables
| Variable | Description |
|---|---|
MSB_SERVER_HOST | Microsandbox server host (overridable via --msb-host) |
MSB_API_KEY | API key for sandbox creation |
HEYO_DEV | Enable development mode (overridable via --dev) |
HEYO_CLOUD_URL | Cloud server URL (overridable via --cloud-url) |
AUTH_SERVER_URL | Auth server URL (overridable via --auth-url) |
HEYO_RELAY_URL | Relay server URL for proxy |
HEYO_ARCHIVE_TOKEN | JWT token for archiving sandboxes |
API_HOSTNAME | Required for bind command |
S3_ENABLED | Enable S3 persistence (true/1 or false/0) |
S3_BUCKET | S3 bucket name |
AWS_REGION | AWS region (default: us-east-1) |
AWS_ENDPOINT_URL | Custom S3 endpoint URL |
Examples
Create a shell sandbox and run a command:
heyvm create --name my-sandbox --type shell
heyvm exec my-sandbox -- echo hello
Create a Python sandbox with a mount:
heyvm create --name py-app --type python --mount ./src:/app/src
heyvm exec py-app -- python -c "print('ok')"
Start an interactive shell:
heyvm sh my-sandbox
Create a worktree sandbox for a feature branch:
heyvm wt feat/new-feature -b
For proxy/connect usage, see Local Tunnels & Proxies.