How to run Firecracker on a Mac (Apple Silicon)
Firecracker is a Linux Virtual Machine Monitor that talks directly to KVM, the Linux kernel's hardware-virtualization interface. macOS has no KVM — it virtualizes through Apple's Hypervisor.framework instead — so Firecracker cannot run natively on a Mac, Apple Silicon or otherwise. The working answer is to run a thin Linux VM on the Mac with nested virtualization enabled, and run Firecracker inside that. On an M1/M2/M3, Apple's Virtualization.framework (exposed by Lima as the `vz` VM type) supports nested virtualization, which lets the guest Linux kernel expose `/dev/kvm` to Firecracker. This is exactly how we develop PandaStack on Macs, and the steps below are distilled from the script we actually use.
Why Firecracker can't run natively on macOS
Firecracker opens `/dev/kvm` and issues KVM ioctls to create vCPUs and memory slots. That device only exists on Linux. There's no port of Firecracker to Hypervisor.framework, and there shouldn't be — Firecracker's whole design is built around the KVM API. So the question isn't "how do I make Firecracker use Apple's hypervisor," it's "how do I get a Linux kernel with KVM running on my Mac." Nested virtualization is what makes that practical: the outer VM (Linux, on Apple VZ) is itself allowed to run an inner VM (your Firecracker microVM).
Prerequisites
- An Apple Silicon Mac (M1/M2/M3 or newer). Intel Macs don't support the nested virtualization this relies on.
- A recent macOS — nested virtualization support in Virtualization.framework is only on newer macOS releases on Apple Silicon. If the KVM check later fails, an OS update is the first thing to try.
- Homebrew, to install Lima.
# Install Lima (the Linux-VM manager that exposes Apple VZ + nested virt)
brew install lima
# Confirm you're on Apple Silicon
uname -m # must print: arm64Step 1 — Create a Linux VM with nested virtualization
Lima boots a Linux VM from a config file. The three settings that matter are `vmType: vz` (use Apple's Virtualization.framework, not QEMU — QEMU on Apple Silicon won't give you working nested KVM), `nestedVirtualization: true`, and an `aarch64` Ubuntu image. Save this as `firecracker.yaml`:
# firecracker.yaml
vmType: vz
arch: aarch64
cpus: 4
memory: 6GiB
disk: 30GiB
nestedVirtualization: true
images:
- location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-arm64.img"
arch: "aarch64"
provision:
- mode: system
script: |
#!/bin/bash
set -euxo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y ca-certificates curl wget squashfs-tools \
iproute2 iptables uuid-runtime e2fsprogs
# Firecracker talks to /dev/kvm; make sure the user can reach it.
groupadd -f kvm
usermod -aG kvm ubuntu || true# Create and start the VM
limactl create --name firecracker --tty=false firecracker.yaml
limactl start --tty=false firecrackerStep 2 — Verify nested KVM is actually available
This is the make-or-break check. If `/dev/kvm` is present and readable/writable inside the Lima guest, nested virtualization is working and Firecracker will run. If it isn't, nothing downstream will work — stop here and fix it (almost always a macOS or Lima version that's too old).
limactl shell firecracker -- sudo bash -lc \
'test -e /dev/kvm && test -r /dev/kvm && test -w /dev/kvm && echo "KVM OK"'
# Expect: KVM OKStep 3 — Install Firecracker inside the VM
Everything from here runs inside the Lima guest, not on macOS. Grab a release binary for `aarch64` (match the VM's architecture) and put it on the path:
limactl shell firecracker -- sudo bash -lc '
set -euo pipefail
FC_VERSION=v1.16.0
ARCH=aarch64
cd /tmp
curl -fL "https://github.com/firecracker-microvm/firecracker/releases/download/${FC_VERSION}/firecracker-${FC_VERSION}-${ARCH}.tgz" -o fc.tgz
tar -xzf fc.tgz
install -m 0755 "release-${FC_VERSION}-${ARCH}/firecracker-${FC_VERSION}-${ARCH}" /usr/local/bin/firecracker
firecracker --version
'Step 4 — Get a guest kernel and root filesystem
A microVM needs two things to boot: an uncompressed Linux kernel (`vmlinux`) and a root filesystem image. The Firecracker project publishes CI artifacts you can use directly — a 5.10 `vmlinux` and an Ubuntu rootfs. Download them inside the VM:
limactl shell firecracker -- sudo bash -lc '
set -euo pipefail
ARCH=aarch64
cd /var/lib
mkdir -p fc && cd fc
# Kernel (uncompressed vmlinux, 5.10 line)
KKEY=$(curl -fsSL "https://s3.amazonaws.com/spec.ccfc.min?prefix=firecracker-ci/v1.13/${ARCH}/vmlinux-5.10&list-type=2" \
| grep -oP "(?<=<Key>)(firecracker-ci/v1.13/${ARCH}/vmlinux-5\.10\.[0-9]+)(?=</Key>)" | sort -V | tail -1)
curl -fL "https://s3.amazonaws.com/spec.ccfc.min/${KKEY}" -o vmlinux
# Root filesystem (Ubuntu squashfs -> ext4)
RKEY=$(curl -fsSL "https://s3.amazonaws.com/spec.ccfc.min?prefix=firecracker-ci/v1.13/${ARCH}/ubuntu-&list-type=2" \
| grep -oP "(?<=<Key>)(firecracker-ci/v1.13/${ARCH}/ubuntu-[0-9]+\.[0-9]+\.squashfs)(?=</Key>)" | sort -V | tail -1)
curl -fL "https://s3.amazonaws.com/spec.ccfc.min/${RKEY}" -o ubuntu.squashfs
unsquashfs -d squashfs-root ubuntu.squashfs >/dev/null
truncate -s 2G rootfs.ext4
mkfs.ext4 -d squashfs-root -F rootfs.ext4 >/dev/null
rm -rf squashfs-root ubuntu.squashfs
ls -lh vmlinux rootfs.ext4
'Step 5 — Boot your first microVM
Firecracker is configured over a REST API on a Unix socket, but the simplest way to boot is a config file passed at launch. Create one describing the kernel, the rootfs drive, and a 1-vCPU / 128 MiB machine:
{
"boot-source": {
"kernel_image_path": "/var/lib/fc/vmlinux",
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
},
"drives": [
{
"drive_id": "rootfs",
"path_on_host": "/var/lib/fc/rootfs.ext4",
"is_root_device": true,
"is_read_only": false
}
],
"machine-config": {
"vcpu_count": 1,
"mem_size_mib": 128
}
}# Save the JSON above as /var/lib/fc/vmconfig.json inside the VM, then:
limactl shell firecracker -- sudo bash -lc '
cd /var/lib/fc
firecracker --no-api --config-file vmconfig.json
'
# You should see a Linux kernel boot on the serial console in well under a second.
# Press Ctrl-C (or `reboot` inside the guest) to stop the microVM.That's a real microVM: its own guest kernel, hardware-isolated by KVM, booting in milliseconds — running inside a Linux VM, running on your Mac. From here you'd add networking (a tap device in a network namespace) and a guest agent to actually do work, which is where it stops being a weekend project and starts being a platform.
Common gotchas
- /dev/kvm missing — the number-one issue. It means nested virtualization isn't active: update macOS and Lima, and make sure vmType is vz (not qemu) and nestedVirtualization is true.
- Architecture mismatch — on Apple Silicon everything is aarch64: the Firecracker binary, the kernel, and the rootfs all must be aarch64. Don't mix in x86_64 artifacts.
- Permission denied on /dev/kvm — add your user to the kvm group (the provision script above does this) or run Firecracker via sudo.
- Kernel won't boot / panics — use an uncompressed vmlinux (not a bzImage), and keep boot_args minimal (pci=off matters for the stripped-down device model).
- Slow or no nested virt with QEMU — Apple Silicon needs the vz backend for working nested KVM; the QEMU backend is not the path here.
Or skip the setup entirely
Running Firecracker on a Mac is a great way to understand the moving parts — the KVM dependency, nested virtualization, the kernel-plus-rootfs boot contract. But for actually building on microVMs, you don't want to hand-manage tap devices, snapshots, networking, and a guest agent on your laptop. That's the gap PandaStack fills: the same Firecracker isolation, with snapshot-restore creates in ~179ms, forking, and a REST/SDK API — no Lima, no kernel wrangling. You write `Sandbox.create(...)` and get a hardware-isolated microVM. The local setup above is how we develop it; the hosted platform is how you'd ship on it.
Frequently asked questions
Can you run Firecracker natively on macOS?
No. Firecracker requires KVM, the Linux kernel's virtualization interface, which macOS does not have (macOS uses Apple's Hypervisor.framework instead). To run Firecracker on a Mac you run a Linux VM with nested virtualization enabled and run Firecracker inside it.
How do I run Firecracker on an Apple Silicon Mac (M1/M2/M3)?
Use Lima to create a Linux VM with vmType set to vz (Apple's Virtualization.framework) and nestedVirtualization set to true, on an aarch64 Ubuntu image. That exposes /dev/kvm inside the guest, after which you install the aarch64 Firecracker binary and boot a microVM with an aarch64 vmlinux kernel and an ext4 rootfs.
Why does Firecracker need /dev/kvm?
Firecracker is a KVM-based VMM: it opens /dev/kvm and uses KVM ioctls to create vCPUs and guest memory. Without /dev/kvm there is no hardware-virtualization interface for it to use, so it cannot start a microVM. On a Mac, /dev/kvm only appears inside a Linux VM that has nested virtualization turned on.
Does nested virtualization for Firecracker work on Intel Macs?
The Apple Silicon path described here relies on nested virtualization in Apple's Virtualization.framework, which is available on Apple Silicon (M-series) Macs with a recent macOS. Intel Macs do not support this, so running Firecracker there is not practical via the same Lima + vz approach.
179ms p50 cold start. Fork, snapshot, and scale to zero.