Skip to main content
A startup failure, a performance problem, or a security setting narrows to a layer first and to a module second. For the end-to-end path of one exec call, see Architecture overview.

Component Inventory (real module layout)

The table below is the authoritative reference for writing documentation and reading the source. All paths are relative to the repository root, with the uniform prefix src/<crate>/.
All source paths on this page are relative to the repository root and follow src/<crate>/. The workspace also contains the cli, shared, shim, and guest crates.

Component Details

BoxliteRuntime (the runtime entry point)

The entry point for creating and managing Boxes. In the SDK it is the object you enter via a with statement.
  • Python: Boxlite — entered with a synchronous with, and Boxlite.default() is synchronous, but its instance methods are async and must be awaited. Source src/boxlite/src/runtime/core.rs.
  • Node: JsBoxlite (there is no bare Boxlite).
  • Responsibilities: Box lifecycle (create/get/get_or_create/list_info/remove/shutdown/import_box), image handle (images), runtime metrics (metrics()).
  • Key fact: listing uses list_info() (not list()); deletion uses remove(id_or_name, force=False) on the runtime (not box.remove()).

LiteBox (a single Box handle)

Every box object is backed by a LiteBox. Source src/boxlite/src/litebox/.
  • Lazy initialization: runtime.create() returns a handle immediately and does not trigger VM startup; the genuinely expensive operations (image pull → rootfs preparation → VM spawn → guest ready) are deferred to the first API call. So in the Python wrapper layer, entering async with SimpleBox(...) is what actually creates and starts the Box.
  • Responsibilities: command execution (exec), metrics, snapshot/clone/export, graceful shutdown.
  • Key fact: box.info() is synchronous (do not await); the returned BoxInfo uses .state (of type BoxStateInfo), and the status string is in BoxStateInfo.status.

ShimController and the VMM

ShimController (src/boxlite/src/vmm/controller/shim.rs) places VM startup in a separate subprocess. The reason: libkrun’s krun_start_enter uses a process-takeover model — once called, it never returns. If it were called directly in the host process, the application process would be permanently taken over. By wrapping it in a subprocess, the host process keeps running, and the jailer is given a sandboxable target. The VMM abstraction (src/boxlite/src/vmm/) is pluggable: the current production implementation is libkrun (src/boxlite/src/vmm/krun/), which handles hardware virtualization, virtio-fs file sharing, virtio-blk disks, and vsock communication.
The VMM layer sits behind a trait, so backends are pluggable. Two are declared today: Libkrun (production default) and Firecracker. Adding one is a runtime-internal change — see CONTRIBUTING.md.
The configuration flow that a Vmm implementation drives when starting a VM is: create the libkrun context → set Box resources (CPUs, memory) → configure the network (TSI or gvproxy) → mount virtiofs shares → attach disk images → configure vsock ports → set the guest entrypoint → return the VM instance.

Jailer (security isolation)

Modeled after Firecracker’s jailer, it adds a layer of OS-level isolation on top of hardware virtualization, sandboxing the shim process. Source src/boxlite/src/jailer/; the threat model is in src/boxlite/src/jailer/THREAT_MODEL.md. For untrusted code, set security explicitly: an explicitly constructed SecurityOptions() has every switch off, so pass SecurityOptions.standard() or .maximum() through advanced (see the Quick Example below).

Portal (host-guest communication)

The gRPC-based communication layer, bridged over libkrun’s vsock. Source src/boxlite/src/portal/.

Guest Agent

Runs inside the Box and receives host commands over gRPC. Source src/guest/src/ (crate boxlite-guest).

Image / Rootfs / Volumes / Net

  • Image (src/boxlite/src/images/): OCI image pull, blob cache by digest, layer extraction and cross-image deduplication, copy-on-write.
  • Rootfs (src/boxlite/src/rootfs/): extracts from image layers and assembles the Box root filesystem via overlay.
  • Volumes (src/boxlite/src/volumes/): virtiofs host-directory mounts, QCOW2 copy-on-write disks.
  • Net (src/boxlite/src/net/): defaults to gvproxy (a user-mode network stack with full outbound access plus port forwarding plus DHCP/DNS), with libslirp as an alternative.

The CLI as a Worked Example of This Layout

The boxlite CLI is a thin client over the same BoxliteRuntime the SDKs use — anything the CLI can do, your code can do, with identical semantics.

Metrics System (real field names)

Metrics come at two levels, both lock-free atomic counters. Field names are not identical across languages, so use the real names from the tables below when writing code. RuntimeMetrics (runtime level, runtime.metrics()): BoxMetrics (per-box level, box.metrics()):
The Node SDK’s metric field names carry a Total suffix and are camelCase (such as numRunningBoxes, boxesCreatedTotal, memoryBytes, cpuPercent), differing from the Python/C/Go names above. When developing across languages, do not assume the field names match.

Directory Layout (runtime on-disk state)

A Box’s runtime data is stored under the home directory (default ~/.boxlite, overridable via BOXLITE_HOME). The tree below follows the dirs constants in the source src/boxlite/src/runtime/layout.rs: