BoxLite is an embeddable virtual machine runtime that follows the SQLite philosophy: a library that can be embedded directly into applications without requiring a daemon or external service.
Terminology: Throughout this documentation, we use "Box" to refer to an isolated execution environment (the underlying implementation uses a lightweight VM). A Box provides hardware-level isolation while presenting a simple, container-like interface.
┌────────────────────────────────────────────────────────────────────┐
│ Host Application │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ BoxliteRuntime │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
│ │ │ BoxManager │ │ImageManager │ │ RuntimeMetrics │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ LiteBox │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
│ │ │ Lifecycle │ │ Exec │ │ Metrics │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ ShimController │ │
│ │ (Spawns shim with jailer isolation) │ │
│ └──────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────┘
│
Spawns subprocess
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ JAILER BOUNDARY (OS Sandbox) │
│ ╔══════════════════════════════════════════════════════════════╗ │
│ ║ Shim Process (boxlite-shim) ║ │
│ ║ - Seccomp filtering (Linux) ║ │
│ ║ - Namespace isolation (Linux) ║ │
│ ║ - sandbox-exec (macOS) ║ │
│ ║ - Resource limits (cgroups/rlimits) ║ │
│ ╚══════════════════════════════════════════════════════════════╝ │
│ │ │
│ Unix Socket / Vsock │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Box (Guest VM) │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ Guest Agent │ │ │
│ │ │ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │ │ │
│ │ │ │ Guest │ │Container │ │ Execution │ │ │ │
│ │ │ │ Service │ │ Service │ │ Service │ │ │ │
│ │ │ └──────────┘ └──────────┘ └──────────────────┘ │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ OCI Container Runtime │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────┘
The main entry point for creating and managing Boxes. Holds all runtime state protected by a single
RwLock.
Source: boxlite/src/runtime/
Key responsibilities:
- Box lifecycle management (create, list, get, remove)
- Image management (pull, cache)
- Runtime-wide metrics collection
- Filesystem layout management
State architecture:
RuntimeInnerImpl
├── sync_state (RwLock)
│ ├── BoxManager # Tracks all Boxes and their states (Source: boxlite/src/management/box_manager.rs)
│ └── ImageManager # OCI image cache and management (Source: boxlite/src/management/image_manager.rs)
└── non_sync_state (immutable)
├── FilesystemLayout # Directory structure (~/.boxlite)
├── InitRootfs # Shared init rootfs for guests
└── RuntimeMetrics # Atomic counters (lock-free)
Individual Box handle providing execution capabilities. Supports lazy initialization - heavy work ( image pulling, Box startup) is deferred until first use.
Source: boxlite/src/litebox/
Key responsibilities:
- Command execution (
exec) - Metrics collection
- Graceful shutdown
Lazy initialization flow:
runtime.create()returns immediately with handle- First API call triggers initialization pipeline
- Pipeline: image pull → rootfs prep → Box spawn → guest ready
Universal subprocess-based Box controller. Spawns boxlite-shim binary in a subprocess to isolate
Box process takeover from the host application.
Source: boxlite/src/vmm/controller/shim.rs, shim/src/main.rs
Why subprocess isolation:
- libkrun performs process takeover (
krun_start_enternever returns) - Subprocess ensures host application continues running
- Clean process tree management
- Enables jailer to sandbox the shim process
Defense-in-depth security layer that sandboxes the shim process, inspired by Firecracker's jailer. Provides OS-level isolation on top of hardware virtualization.
Source: boxlite/src/jailer/
Key responsibilities:
- OS-level process isolation for shim
- Syscall filtering and sandboxing
- Resource limit enforcement
- Environment sanitization
Security layers:
Linux:
- Namespace isolation (mount, PID, network)
- Chroot/pivot_root for filesystem isolation
- Seccomp BPF for syscall filtering
- Privilege dropping (unprivileged user)
- cgroups v2 for resource limits
macOS:
- sandbox-exec (Seatbelt) for kernel-enforced sandboxing
- rlimits for resource constraints
Architecture:
┌─────────────────────────────────────────────────────────────────────┐
│ HOST OS │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ JAILER BOUNDARY │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ SHIM PROCESS (sandboxed) │ │ │
│ │ │ ┌───────────────────────────────────────────────────┐ │ │ │
│ │ │ │ VM (libkrun/KVM) │ │ │ │
│ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │
│ │ │ │ │ GUEST (untrusted) │ │ │ │ │
│ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │
│ │ │ └───────────────────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Configuration:
use boxlite::{AdvancedBoxOptions, SecurityOptions};
// Most users don't need to configure security — defaults prioritize compatibility
// For advanced users who need maximum isolation:
let opts = BoxOptions {
advanced: AdvancedBoxOptions {
security: SecurityOptions::enabled(),
..Default::default()
},
..Default::default()
};For complete threat model and security design, see: boxlite/src/jailer/THREAT_MODEL.md
gRPC-based communication layer between host and guest.
Components:
GuestSession: High-level facade for service interfacesConnection: Lazy gRPC channel management- Service interfaces:
GuestInterface,ContainerInterface,ExecutionInterface
Runs inside the Box, receives commands from host via gRPC.
Source: guest/ (crate: boxlite-guest)
Services:
Guest: Environment initialization (mounts, rootfs, network)Container: OCI container lifecycle management (via libcontainer)Execution: Command execution with streaming I/O
Guest-side modules:
container/: OCI container lifecycle using libcontainerstorage/: Filesystem mounts and overlayfs managementnetwork.rs: Virtual NIC configuration and DHCP
BoxLite uses OCI-compatible container images with intelligent caching.
Location: boxlite/src/images/
ImageManager
├── ImageStore # OCI blob storage and retrieval
├── ImageStorage # Layer extraction and caching
└── Archive handlers # TAR archive processing
Registry (Docker Hub, GHCR, ECR, etc.)
│
▼
┌─────────────────────┐
│ OCI Client │ Pull manifest and layers
└─────────────────────┘
│
▼
┌─────────────────────┐
│ ImageStore │ Store blobs in ~/.boxlite/images/blobs/
└─────────────────────┘
│
▼
┌─────────────────────┐
│ Layer Extraction │ Extract to cached layer directories
└─────────────────────┘
│
▼
┌─────────────────────┐
│ Rootfs Assembly │ Combine layers for Box rootfs
└─────────────────────┘
- Blob-level caching: Image layers stored by digest, shared across images
- Layer deduplication: Common base layers (e.g., debian:slim) extracted once
- Copy-on-write: Boxes share base layers, only modifications are per-Box
Location: boxlite/src/rootfs/
The rootfs builder assembles a container filesystem from OCI image layers:
Image Layers Rootfs Builder Box Rootfs
┌─────────┐ ┌─────────────┐ ┌─────────────┐
│ Layer 1 │────┐ │ │ │ /bin │
├─────────┤ │ │ Extract & │ │ /etc │
│ Layer 2 │────┼────▶│ Overlay │─────────▶│ /usr │
├─────────┤ │ │ │ │ /var │
│ Layer N │────┘ └─────────────┘ │ ... │
└─────────┘ └─────────────┘
Key operations:
- Layer extraction and overlay mounting
- DNS configuration injection
- Copy-on-write snapshot creation
Location: boxlite/src/volumes/
Supported volume types:
| Type | Description | Use Case |
|---|---|---|
| virtiofs | Host directory mount | Sharing files with Box |
| QCOW2 disk | Copy-on-write disk image | Persistent storage |
QCOW2 features:
- Thin provisioning (allocate on write)
- Snapshot support
- Shared base images across Boxes
BoxLite supports pluggable network backends for Box connectivity.
Location: boxlite/src/net/
pub trait NetworkBackend: Send + Sync {
fn start(&mut self) -> BoxliteResult<NetworkConfig>;
fn stop(&mut self) -> BoxliteResult<()>;
fn metrics(&self) -> NetworkMetrics;
}User-mode networking based on gVisor's network stack.
Box gvproxy Internet
┌──────┐ ┌───────┐ ┌──────────┐
│ eth0 │◄────vsock───▶│ │◄────TCP/UDP─▶│ │
└──────┘ │ NAT │ │ External │
│ DHCP │ │ Services │
│ DNS │ └──────────┘
└───────┘
Features:
- Full outbound internet access
- Port forwarding (TCP/UDP)
- Built-in DHCP and DNS
- Network metrics (bytes sent/received)
QEMU's user-mode networking stack.
Use case: Environments where gvproxy isn't available.
Boxes receive network configuration via DHCP:
- IP address from virtual subnet
- Default gateway
- DNS servers (configurable, defaults to host resolvers)
BoxLite uses a pluggable Vmm (Virtual Machine Monitor) architecture for Box execution.
Location: boxlite/src/vmm/
pub trait Vmm {
fn create(&mut self, config: InstanceSpec) -> BoxliteResult<VmmInstance>;
}Represents a configured Box ready to execute:
pub struct VmmInstance {
inner: Box<dyn VmmInstanceImpl>,
}
impl VmmInstance {
/// Transfer control to the Box (may never return)
pub fn enter(self) -> BoxliteResult<()>;
}Current production Vmm implementation using libkrun hypervisor.
Features:
- Hardware virtualization (macOS Hypervisor.framework, Linux KVM)
- virtio-fs for filesystem sharing
- virtio-blk for disk images
- vsock for host-guest communication
- Process takeover model (
krun_start_enter)
Configuration flow:
- Create libkrun context
- Set Box resources (CPUs, memory)
- Configure network (TSI or gvproxy)
- Mount virtiofs shares
- Attach disk images
- Configure vsock ports
- Set guest entrypoint
- Return
VmmInstance
To add a new Vmm implementation:
- Implement
Vmmtrait - Implement
VmmInstanceImplfor the instance type - Register in
VmmFactory - Add
VmmKindvariant
Communication uses gRPC over transport channels, bridged via libkrun's vsock support.
Host Application
│
│ Unix Socket (/tmp/boxlite-{id}.sock)
▼
┌─────────────────┐
│ libkrun vsock │ (Unix socket ↔ vsock bridge)
│ bridge │
└─────────────────┘
│
│ Vsock (port 2695)
▼
Guest Agent (gRPC Server)
Defined in boxlite-shared/proto/boxlite/v1/service.proto:
service Guest {
rpc Init(GuestInitRequest) returns (GuestInitResponse);
rpc Ping(PingRequest) returns (PingResponse);
rpc Shutdown(ShutdownRequest) returns (ShutdownResponse);
}
service Container {
rpc Init(ContainerInitRequest) returns (ContainerInitResponse);
}
service Execution {
rpc Exec(ExecRequest) returns (ExecResponse);
rpc Attach(AttachRequest) returns (stream ExecOutput);
rpc SendInput(stream ExecStdin) returns (SendInputAck);
rpc Wait(WaitRequest) returns (WaitResponse);
rpc Kill(KillRequest) returns (KillResponse);
rpc ResizeTty(ResizeTtyRequest) returns (ResizeTtyResponse);
}Host Guest (Box)
│ │
│──── spawn Box subprocess ──────▶│
│ │
│◀─── ready notification ─────────│ (vsock connect to port 2696)
│ │
│──── Guest.Init ────────────────▶│ (mounts, rootfs, network)
│◀─── GuestInitResponse ──────────│
│ │
│──── Container.Init ────────────▶│ (OCI container setup)
│◀─── ContainerInitResponse ──────│
│ │
│──── Execution.Exec ────────────▶│ (run commands)
│◀─── streaming stdout/stderr ────│
│ │
BoxLite provides comprehensive metrics at runtime and per-Box levels.
Location: boxlite/src/metrics/
┌─────────────────────────────────────────┐
│ RuntimeMetrics │
│ ┌─────────────────────────────────┐ │
│ │ AtomicU64 counters (lock-free) │ │
│ │ - boxes_created │ │
│ │ - boxes_destroyed │ │
│ │ - total_exec_calls │ │
│ │ - total_bytes_transferred │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ BoxMetrics (per-Box) │
│ - cpu_time_ms │
│ - memory_usage_bytes │
│ - exec_count │
│ - network_bytes_sent │
│ - network_bytes_received │
└─────────────────────────────────────────┘
- Lock-free: Uses
AtomicU64for concurrent updates without synchronization - Low overhead: Metrics collection doesn't impact Box performance
- Hierarchical: Runtime-wide aggregates + per-Box details
BoxLite provides language-specific SDKs built on the core Rust library.
┌─────────────────────────────────────────┐
│ Host Application │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Language SDK (Python, Node, C) │
│ (Native bindings) │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ BoxLite Core (Rust) │
└─────────────────────────────────────────┘
| SDK | Technology | Status | Location |
|---|---|---|---|
| Python | PyO3 + maturin | Available | sdks/python/ |
| Node.js | napi-rs | In Progress | sdks/node/ |
| C | FFI + cbindgen | Available | sdks/c/ |
The boxlite-shared crate contains data types, error definitions, and constants shared between the
host runtime, the shim, and the guest agent.
Location: boxlite-shared/
Key Components:
BoxliteError: Centralized error type.Constants: Shared constants (e.g. socket paths, default ports).Transport: gRPC transport utilities.
Default home directory: ~/.boxlite
~/.boxlite/
├── boxes/ # Per-Box runtime data
│ └── {box-id}/
│ ├── rootfs/ # Container rootfs
│ └── config.json
├── images/ # OCI image cache
│ ├── blobs/ # Image layer blobs (by digest)
│ └── index.json # Image index
├── init/ # Shared init rootfs
│ └── rootfs/
├── logs/ # Runtime logs
│ └── boxlite.log # Daily rotating log
└── boxlite.lock # Runtime lock file (prevents multiple instances)
BoxliteRuntime:Send + Sync, safely shareable across threadsLiteBox:Send + Sync, handles can be passed between threads- Single
RwLockprotects all mutable runtime state - Metrics use
AtomicU64for lock-free updates
BoxLite uses one RwLock for all mutable state:
- Eliminates nested locking complexity
- Simplifies reasoning about concurrency
- Filesystem lock prevents multiple runtimes using same
BOXLITE_HOME
- All I/O operations are async (Tokio runtime)
- Streaming operations use
futures::Stream - gRPC uses tonic's async support
Centralized error type: BoxliteError
pub enum BoxliteError {
UnsupportedEngine,
Engine(String),
Storage(String),
Image(String),
Portal(String),
Network(String),
Rpc(String),
RpcTransport(String),
Internal(String),
Execution(String),
}All public APIs return BoxliteResult<T> = Result<T, BoxliteError>.