Architecture
Big picture
Lima splits into three layers: a CLI (limactl), a per-instance host daemon (the hostagent), and an agent inside the guest (the guestagent). The CLI parses templates and orchestrates lifecycle; the hostagent runs as a long-lived child process that drives the VM through a pluggable driver and manages SSH, mounts, port forwarding, and DNS; the guestagent runs in the VM and streams events back to the host. The main() entry point is a cobra app at cmd/limactl/main.go:33.
Components
CLI: cmd/limactl
The user-facing binary, built with cobra. It implements start, stop, shell, list, edit, snapshot, and more. main() lives at cmd/limactl/main.go:33. The lima binary is a thin wrapper around limactl shell.
Instance lifecycle: pkg/instance
Owns create/start/stop for an instance. Create is at pkg/instance/create.go:24, Prepare at pkg/instance/start.go:50, and Start at pkg/instance/start.go:286, which calls StartWithPaths at pkg/instance/start.go:168.
Host daemon: pkg/hostagent
A daemon launched as the child process limactl hostagent <name>. It boots the VM via the driver and manages SSH, mounts, port forwarding, and DNS. New is at pkg/hostagent/hostagent.go:128 and Run at pkg/hostagent/hostagent.go:389.
Driver layer: pkg/driver and pkg/driver/{qemu,vz,wsl2,krunkit}
The VM backend abstraction. The Driver interface is defined at pkg/driver/driver.go:81, and Info (capability flags) at pkg/driver/driver.go:110. Both in-tree drivers and external gRPC plugins implement it.
Guest agent: pkg/guestagent and cmd/lima-guestagent
Runs inside the VM and exposes a gRPC GuestService over vsock/virtio, defined at pkg/guestagent/api/guestservice.proto:8. It notifies the host of port events, inotify changes, and time sync.
Provisioning: pkg/cidata
Generates the cloud-init ISO9660 (user-data) image that provisions the guest. GenerateCloudConfig is at pkg/cidata/cidata.go:361 and GenerateISO9660 at pkg/cidata/cidata.go:386.
How a request flows
limactl start <name> walks through the layers as follows (anchors at the pinned commit):
startActionatcmd/limactl/start.go:570callsloadOrCreateInstanceatcmd/limactl/start.go:215to build or load the instance from a template.- Networking is reconciled via
reconcile.Reconcileatcmd/limactl/start.go:599. instance.Startatcmd/limactl/start.go:626callsStartatpkg/instance/start.go:286, thenStartWithPathsatpkg/instance/start.go:168.StartWithPathsbuilds the"hostagent"argument (pkg/instance/start.go:218), constructshaCmd = exec.CommandContext(...)atpkg/instance/start.go:234, and launches it in the background withhaCmd.Start()atpkg/instance/start.go:249.- The child process enters
hostagentActionatcmd/limactl/hostagent.go:43, which callshostagent.Newatcmd/limactl/hostagent.go:109and thenha.Runatcmd/limactl/hostagent.go:136. - Inside
New(pkg/hostagent/hostagent.go:128), the driver is resolved and the cloud-init ISO is built withcidata.GenerateISO9660atpkg/hostagent/hostagent.go:188. Runatpkg/hostagent/hostagent.go:389boots the VM witha.driver.Start(ctx)atpkg/hostagent/hostagent.go:424, then callsstartRoutinesAndWaitatpkg/hostagent/hostagent.go:498.startHostAgentRoutinesatpkg/hostagent/hostagent.go:543waits for SSH readiness, sets up mounts, and startswatchGuestAgentEventsatpkg/hostagent/hostagent.go:697to apply port forwarding.
Key design decisions
- Configuration as data, not push. Guest configuration is injected at boot through a cloud-init ISO9660 image generated by
pkg/cidata(GenerateISO9660atpkg/cidata/cidata.go:386), rather than pushing config to a running agent. - gRPC over vsock/virtio for host/guest events. The guestagent serves
GuestService(pkg/guestagent/api/guestservice.proto:8), whereGetEventsis a server stream. SSH carries shell and command execution and port forwarding; event notification prefers the vsock gRPC channel. - Driver interface keeps backends swappable. A single
Driverinterface (pkg/driver/driver.go:81) lets QEMU, vz, WSL2, krunkit, and external drivers be selected per instance.
Extension points
- External drivers as separate processes. Out-of-tree backends implement the gRPC
service Driver(pkg/driver/external/driver.proto:7) and run as their own executables, registered in theExternalDriversmap (pkg/registry/registry.go:42). - Templates. YAML templates under
templates/define reusable instance configurations. - Wrapper binaries.
cmdshipsnerdctl.lima,docker.lima,kubectl.lima,podman.lima, andapptainer.limawrappers plus per-driver binaries.
Sources
- Lima source at commit
9a3f1c4, accessed 2026-06-24. - lima-vm/lima README, accessed 2026-06-24.