Skip to content

Install mvm on macOS

mvm on macOS is supported on Apple Silicon (M-series). The local builder/runtime path uses Apple’s Hypervisor.framework via Apple Container and libkrun-backed components. No Docker Desktop is required for the supported path.

For the full host/backend matrix, see Platform support.

Intel Macs are not a supported local microVM host. Use a Linux machine with /dev/kvm or a remote Linux builder/runtime if you need first-class isolation from Intel macOS.

  • Apple Silicon Mac.
  • macOS 26+ for the Apple Container dev VM path.
  • libkrun installed for libkrun-backed builder/runtime components.

You do not need Nix on your Mac. You run mvmctl build from macOS, and mvm runs Nix evaluation and nix build inside the Linux builder VM, then extracts the resulting rootfs back to the host. See §“Linux builds on macOS” below for the design.

Terminal window
curl -fsSL https://raw.githubusercontent.com/tinylabscom/mvm/main/install.sh | sh
Terminal window
MVM_VERSION=v0.13.0 curl -fsSL https://raw.githubusercontent.com/tinylabscom/mvm/main/install.sh | sh
Terminal window
git clone https://github.com/tinylabscom/mvm.git
cd mvm
cargo build --release
install -m 0755 target/release/mvmctl ~/.local/bin/mvmctl
Terminal window
cargo install mvmctl

mvmctl is a regular Mach-O binary on macOS — no codesigning surprises in the typical install path. Hypervisor.framework requires the host process to hold the com.apple.security.hypervisor entitlement; the install script handles ad-hoc signing automatically. If you build from source via cargo, the same entitlement is added by the build script.

macOS Nix can’t build Linux derivations natively, and most Mac users don’t have Nix installed at all. mvm handles both cases without requiring host-side configuration: on mvmctl build, the host CLI stages the selected flake as a builder job, the Linux builder VM runs nix build, and mvm copies the resulting kernel/rootfs artifacts back to the host cache. See Builder VM for the full control-plane flow.

The builder VM is separate from the runtime VM. After the build completes, mvmctl up --hypervisor apple-container boots the already-built runtime image with Apple Virtualization. The build phase and boot phase can be benchmarked separately.

Most users skip this section. You may want host-side Nix if you’re contributing to mvm itself, want Nix for editor tooling, or already run nix-darwin for unrelated reasons. Host-side Nix is not required by mvmctl build; the builder VM remains the Linux build boundary for mvm images.

Determinate Nix is the easiest path:

Terminal window
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install

If you configure nix-darwin’s linux-builder, it can be useful for direct nix build commands that you run yourself. It is not required for mvmctl build.

Terminal window
mvmctl doctor

doctor reports the active backend and libkrun availability. On an Apple Silicon Mac with macOS 26+, the dev path uses Apple Container and source image builds use the libkrun-backed builder VM.

Terminal window
mkdir my-app && cd my-app
mvmctl init
mvmctl run

mvmctl init scaffolds the project. On first mvmctl run, mvm bootstraps the builder VM if needed, runs nix build inside it, and boots the resulting rootfs with the selected macOS runtime backend. Expected runtime cold boot is measured after the image is already built. When developing from this source checkout, the builder VM image is local-build only; the cache is reused only when its source fingerprint matches nix/images/builder-vm/{flake.nix,flake.lock}, its recorded artifact digests still match the cached files, and its provenance summary matches the same source and artifact filename set. Cache misses, fingerprint drift, artifact drift, or provenance drift build from the local nix/images/builder-vm/ flake using a local dev image as Stage 0, validate the staged artifacts, and only then promote them into the live cache. Run with --verbose to see the safe source-cache reason code, for example hit, fingerprint_mismatch, artifact_digest_mismatch, or provenance_mismatch. mvm will not download a published builder image to hide local flake changes.

“Hypervisor.framework: entitlement missing” — re-codesign the binary with the entitlement: codesign --entitlements resources/mvmctl.entitlements -f -s - ~/.local/bin/mvmctl. The release binary ships pre-signed; this only matters if you’ve stripped entitlements or built from source without the build script’s signing step.

nix build fails with “a ‘x86_64-linux’ with features … is required” — that is a direct host-side Nix command failing because macOS cannot build Linux derivations by itself. Use mvmctl build --flake . so the Linux build runs inside the builder VM. If you intentionally want direct nix build on macOS, configure nix-darwin’s linux-builder.

mvmctl run boots but mvmctl console fails to attach — the console subcommand is only enabled for accessible images. If your entrypoint.command = [ ... ], the build is sealed and console attach is rejected. Switch to entrypoint.shell = "/bin/sh" or pass dev = true in your mkGuest call. See Building MicroVM Images.

“libkrun shared library not found” — install libkrun, then rerun the command. On Apple Silicon with Homebrew:

Terminal window
brew install libkrun
  • Apple Silicon (M1/M2/M3/M4 and newer) — supported local path. Apple Container covers the dev VM, and libkrun backs builder/runtime components that need Hypervisor.framework directly.
  • Intel Macs — unsupported for the local microVM path. Run mvm on a Linux KVM host, or use future remote/Windows-style builder work when it lands.

The Apple Container backend requires Apple Silicon and macOS 26+. libkrun is also treated as an Apple Silicon macOS path for mvm support purposes.