Getting Started
First-Use Happy Paths
Three-command paths to get a microVM running for each mvm audience.
mvm has six primary audiences. Each one has a three-command happy
path that takes you from “I have a thing to run” to “it’s running
under mvm.” Pair each path with mvmctl doctor --workflow <name> to
preflight only the host requirements that matter for your audience —
nothing more, nothing less.
| Audience | Preflight | What you’re doing |
|---|---|---|
| CLI user with an OCI image | --workflow cli-run | Run a command in a transient image-backed microVM. |
| CLI user with a flake | --workflow cli-run | Boot a microVM from a Nix flake. |
| Python SDK user | --workflow python-sdk | Run a @mvm.app()-decorated Python script. |
| TypeScript / Node SDK user | --workflow typescript-sdk | Run an mvm.app() TypeScript app. |
| Prebuilt bundle operator | --workflow bundle-run | Launch a signed .mvmpkg artifact. |
| Interactive shell user | --workflow dev-shell | Boot a dev-tier image and drop into an interactive shell. |
The preflight filter (plan 74 W5 / ADR-017 §1) only fails on missing
prerequisites your workflow actually needs. A bundle operator no
longer sees a “missing cargo” failure they don’t care about; an
interactive-shell user no longer needs host rustup.
CLI user with an OCI image
Section titled “CLI user with an OCI image”You have an OCI image reference and want to run one command in a fresh microVM without writing a flake or installing host Nix.
mvmctl doctor --workflow cli-run # preflightmvmctl run --image alpine -- uname -a # pull/cache, boot, run, tear downmvmctl image inspect alpine # inspect cached provenanceThe first run may pull and materialize the image. Subsequent runs reuse the cache when the resolved image and policy inputs still match. Production image runs should use digest-pinned refs and the existing OCI policy verification path.
For the higher-level mvmctl machine workflow map, see
Machine use cases. For explicit network, volume,
macOS, GPU, and architecture limits, see
Machine limitations.
Failure recovery:
image verification failed→ use a digest-pinned image and configure the OCI policy expected by your environment.host nix not requirederrors → none expected. Image-backed one-shot runs do not require host Nix.- Network failures from inside the guest → current one-shot image networking is
governed by the runtime network policy. The planned
machineUX will expose a simpler explicit--net/--allow-hostsurface.
CLI user with a flake
Section titled “CLI user with a flake”You have a flake.nix (or want to scaffold one) and want a microVM
booted from it.
mvmctl doctor --workflow cli-run # preflightmvmctl machine run --flake . --cpus 2 --memory 1024 # build + bootmvmctl machine stop --all # tear downThe first run downloads the builder VM image (or builds it from a
source checkout); subsequent runs reuse the warm builder. Skip the
--cpus / --memory flags to get the defaults from
~/.mvm/config.toml.
Failure recovery:
host nix not requirederrors → none expected. mvm’s builder VM owns Nix; the host doesn’t need it.skipped — dev VM not running; run mvmctl bootstrap to verify→ that’s just doctor telling you tool checks were skipped because the builder VM is asleep. It’s not a failure;mvmctl machine runboots it on demand.disk space < N GiB→ free space on~/.mvm/(default cache location);mvmctl cache infoshows what’s there.
Python SDK user
Section titled “Python SDK user”You have a Python file with an @mvm.app() decorator. mvm compiles
the script to an artifact, builds the rootfs, and exposes it as a
callable function.
mvmctl doctor --workflow python-sdk # preflightmvmctl build compile my_app.py --out /tmp/my-app # compile (static parse)echo '[[], {"name":"ari"}]' | \ mvmctl machine run --entrypoint --flake /tmp/my-app # build + boot + call → "hello ari"mvmctl build compile parses the decorator statically; user code does not
execute on the host (only inside the microVM). mvmctl machine run --entrypoint
invokes the baked function, taking its arguments as an [args, kwargs] JSON
payload on stdin (empty ⇒ [[], {}]). See
SDK guide for the decorator surface.
Failure recovery:
app_deps_gate refused(prod profile) → CVE finding in your dependencies’ sealed volume.mvmctl deps inspect <vol>shows the offending entries;--devadmits high-severity findings for local iteration.compile error: missing @mvm.app() decorator→ the file must declare exactly one decorated function.
TypeScript / Node SDK user
Section titled “TypeScript / Node SDK user”Same shape as the Python flow with a .ts (or .js) entry file.
mvmctl doctor --workflow typescript-sdk # preflightmvmctl build compile my-app.ts --out /tmp/my-app # compile (static parse)echo '[[], {"name":"ari"}]' | \ mvmctl machine run --entrypoint --flake /tmp/my-app # build + boot + call → "hello ari"The preflight specifically checks the local TypeScript runner
(bun, tsx, or deno) — pick the one your project uses. doctor --workflow typescript-sdk flags it if none of them are available.
Failure recovery:
no TypeScript runner found→ install one ofbun,tsx, ordeno. mvm picks whichever is on$PATH.
Prebuilt bundle operator
Section titled “Prebuilt bundle operator”You’re not building anything — you have a signed .mvmpkg artifact
to launch.
mvmctl doctor --workflow bundle-run # preflight (no host rust needed)mvmctl machine check-artifact ./my-app.mvm # verify the signed artifact before launchmvmctl machine stop --all # tear downbundle-run doctor scope explicitly drops prerequisites and
tools — a missing host cargo or builder-VM Nix doesn’t block
bundle launches. The platform + security + disk-space checks
remain.
Failure recovery:
bundle signature invalid→ the.mvmpkg’s manifest signature didn’t match the local trust store. Source bundles from a trusted publisher;mvmctl bundle fetch <path>exits non-zero on mismatch without launching.bundle pin missing(audit-chain admission) → the supervisor’s signed-plan path failed to find a matchingPlanArtifact. Pull a fresh copy from the publisher.
Interactive shell user
Section titled “Interactive shell user”You want a shell inside a microVM — for building, testing, or just
exploring. There’s no standalone dev VM to boot into anymore: the
builder VM is headless (it only exists to run nix build on your
behalf), so an interactive shell means booting a dev-tier workload
and attaching your terminal to it.
mvmctl doctor --workflow dev-shell # preflight (no host rust needed)mvmctl machine run --image alpine -it -- /bin/sh # boot + drop into shell# inside the shell: do work; exit / Ctrl+D tears the VM downmachine run -it boots a fresh transient microVM and is foreground-only
— exiting the shell tears the VM down, the same as any other transient
machine run. For a shell you can leave running and re-enter later, use
a persistent machine instead: mvmctl machine create devbox --image alpine, then mvmctl machine start devbox and mvmctl machine shell devbox.
Failure recovery:
skipped — dev VM not running; run mvmctl bootstrap to verify→ only relevant when your source is--flake(an OCI--imagerun pulls the image directly and never touches the builder VM);mvmctl bootstrappre-fetches the builder VM image, or builds it locally from a source checkout where the in-repo flakes are always preferred over published artifacts.- Shell exits immediately with no output →
mvmctl machine logs <name>shows the kernel/init transcript; pass--nameon the run so you have a name to look it up by.
See also
Section titled “See also”mvmctl doctor— the full diagnostic command, including the--workflowflag added by plan 74 W5.- Quick Start — the broader feature tour.
- Your First MicroVM — write a Nix flake from scratch.
- SDK guide — the Python and TypeScript decorator surface in detail.
- Sandboxed Exec — one-shot transient microVMs
for
docker run --rm-style use. - Machine use cases — scenario-led
mvmctl machineworkflows. - Machine limitations — explicit backend and feature limits for machine UX.