Complete reference for BoxLite APIs, configuration, and error handling.
Complete API documentation for each SDK:
| SDK | Documentation | Description |
|---|---|---|
| Python | Python API Reference | Async/sync API, box types, metrics |
| Node.js | Node.js API Reference | TypeScript definitions, box types, CDP endpoints |
| Rust | Rust API Reference | Core runtime, stream APIs, security options |
| C | C API Reference | FFI bindings, typed options, callback streaming |
| Surface | Documentation | Description |
|---|---|---|
boxlite |
CLI Reference | All subcommands, global flags, volume/port grammar, installation & verification, exit codes |
For complete Python API documentation, see Python API Reference.
Key Classes:
| Class | Description |
|---|---|
Boxlite |
Main runtime for creating and managing boxes |
Box |
Handle to a running or stopped box |
SimpleBox |
Context manager for basic execution |
CodeBox |
Specialized box for Python code execution |
BrowserBox |
Box configured for browser automation |
ComputerBox |
Box with desktop automation capabilities |
InteractiveBox |
Box for interactive shell sessions |
For complete Node.js API documentation, see Node.js API Reference.
Key Classes:
| Class | Description |
|---|---|
SimpleBox |
Basic container for command execution |
CodeBox |
Python code execution sandbox |
BrowserBox |
Browser automation with CDP endpoint |
ComputerBox |
Desktop automation (14 methods) |
InteractiveBox |
PTY terminal sessions |
For complete Rust API documentation, see Rust API Reference.
Core Types:
use boxlite::{
BoxliteRuntime, // Main runtime
BoxOptions, // Box configuration
LiteBox, // Box handle
BoxCommand, // Command builder
RootfsSpec, // Rootfs specification
VolumeSpec, // Volume mount specification
PortSpec, // Port forwarding specification
};For complete C API documentation, see C API Reference.
Functions:
| Function | Description |
|---|---|
boxlite_runtime_new |
Create runtime instance |
boxlite_create_box |
Create a new box |
boxlite_execute |
Run command with streaming |
boxlite_stop_box |
Stop and free box |
For the complete CLI reference, see CLI Reference.
Common subcommands:
| Command | Description |
|---|---|
boxlite run |
Create a box from an image and run a command |
boxlite exec |
Run a command inside a running box |
boxlite list |
List boxes (aliases: ls, ps) |
boxlite cp |
Copy files between host and box |
boxlite inspect |
Show detailed box info (JSON, YAML, or Go template) |
boxlite serve |
Start the long-running REST API server |
Complete reference for box configuration options.
OCI image URI to use for the box rootfs.
Format: [registry/]repository[:tag]
Default: "python:slim" (for Python SDK convenience wrappers)
Examples:
# Docker Hub (default registry)
image="python:3.11-slim"
image="alpine:latest"
image="ubuntu:22.04"
# GitHub Container Registry
image="ghcr.io/owner/repo:tag"
# Amazon ECR
image="123456.dkr.ecr.us-east-1.amazonaws.com/repo:tag"
# Google Container Registry
image="gcr.io/project/image:tag"Notes:
- Images are pulled on first use and cached in
~/.boxlite/images/ - Layer-level caching for fast subsequent starts
- Authentication: Use registry-specific auth (Docker credentials, etc.)
Structured network configuration for outbound connectivity.
Default: omitted, which behaves like:
{
"mode": "enabled",
"allow_net": []
}Shape:
mode:"enabled"or"disabled"allow_net: optional outbound allowlist used only whenmode="enabled"
Notes:
"enabled"gives the guest outbound connectivity."disabled"removes the guest network interface entirely.- Empty or omitted
allow_netmeans full outbound access. host.boxlite.internalis always available as a built-in hostname for reaching host loopback services and is not governed byallow_net.- Security: when networking is enabled, any service bound to host loopback can
be reached from inside the box via
host.boxlite.internalor192.168.127.254.
Supported patterns:
- Exact hostname:
"api.openai.com" - Wildcard hostname:
"*.example.com" - Exact IP:
"192.168.1.10" - CIDR range:
"10.0.0.0/8"
Host-side secret substitution rules for outbound HTTP(S) requests.
Shape:
name: human-readable secret namevalue: real secret valuehosts: matching hosts for substitutionplaceholder: optional guest-visible token, defaults to<BOXLITE_SECRET:{name}>
Notes:
- The guest sees only the placeholder, never the real secret value.
- The placeholder is also exposed as
BOXLITE_SECRET_<NAME>inside the guest. - C SDK users configure secrets with
boxlite_options_add_secret().
Number of CPU cores allocated to the box.
Default: 1
Range: 1 to host CPU count
Example:
cpus=2 # 2 CPU cores
cpus=4 # 4 CPU coresNotes:
- CPU scheduling is proportional (shares-based)
- Does not reserve physical cores, just scheduling weight
- Monitor actual usage with
box.metrics().cpu_time_ms
Memory limit in mebibytes (MiB).
Default: 512
Range: 128 to 65536 (64 GiB)
Example:
memory_mib=1024 # 1 GB
memory_mib=2048 # 2 GB
memory_mib=4096 # 4 GBNotes:
- 1 MiB = 1024 KiB = 1,048,576 bytes
- Minimum 128 MiB required for most images
- Out of memory kills the box process
- Monitor with
box.metrics().memory_usage_bytes
Create a persistent QCOW2 disk image.
Default: None (ephemeral storage only)
Range: 1 to 1024 (1 TB)
Example:
disk_size_gb=None # Ephemeral (default)
disk_size_gb=10 # 10 GB persistent disk
disk_size_gb=100 # 100 GB persistent diskNotes:
- Disk persists across stop/restart
- Stored at
~/.boxlite/boxes/{box-id}/disk.qcow2 - Copy-on-write (thin provisioned)
- Deleted when box is removed
Working directory for command execution inside the box.
Default: "/root"
Example:
working_dir="/app"
working_dir="/home/user/project"Notes:
- Directory must exist in the container image
- Commands execute with this as
$PWD
Environment variables as (key, value) pairs.
Default: [] (inherit from image)
Example:
env=[
("DATABASE_URL", "postgresql://localhost/db"),
("API_KEY", "secret"),
("DEBUG", "true"),
("PATH", "/custom/bin:/usr/bin:/bin"), # Override PATH
]Notes:
- Variables are appended to image environment
- Use to override image defaults (e.g.,
PATH) - Sensitive values (API keys, passwords) are visible in box metadata
Volume mounts as (host_path, guest_path, mode) tuples.
Format: (host_path, guest_path, "ro"|"rw")
Default: [] (no mounts)
Example:
volumes=[
# Read-only mount (data input)
("/host/config", "/etc/app/config", "ro"),
# Read-write mount (data output)
("/host/data", "/mnt/data", "rw"),
# Home directory mount
(os.path.expanduser("~/Documents"), "/mnt/docs", "ro"),
]Notes:
- Uses virtiofs for high-performance file sharing
- Host path must exist before box creation
- Guest path is created automatically if missing
- Changes to
rwmounts are visible on host immediately
Port forwarding as (host_port, guest_port, protocol) tuples.
Format: (host_port, guest_port, "tcp"|"udp")
Default: [] (no port forwarding)
Example:
ports=[
(8080, 80, "tcp"), # HTTP
(8443, 443, "tcp"), # HTTPS
(5432, 5432, "tcp"), # PostgreSQL
(53, 53, "udp"), # DNS
(3000, 8000, "tcp"), # Custom mapping
]Notes:
- Uses gvproxy for NAT port mapping
- Host port must be available (not in use)
- Multiple boxes can forward to same host port (error if conflict)
- Supports both TCP and UDP protocols
- Port mappings are only for host → box traffic. Use
host.boxlite.internal:<port>for box → host loopback traffic.
Automatically remove box when stopped.
Default: True
Example:
auto_remove=True # Auto cleanup (default)
auto_remove=False # Manual cleanup requiredNotes:
True: Box is removed when context exits orstop()is calledFalse: Box persists after stop, can be restarted withruntime.get(box_id)- Manual cleanup:
await box.remove()
Base directory for BoxLite runtime data.
Default: ~/.boxlite
Override: Set BOXLITE_HOME environment variable
Structure:
~/.boxlite/
├── images/ # OCI image cache (blobs, index.json)
├── boxes/ # Per-box data (config.json, disk.qcow2)
├── init/ # Shared guest rootfs
├── logs/ # Runtime logs
├── gvproxy/ # Network backend binaries
├── lock # Filesystem lock file
└── db/ # SQLite databases (boxes.db, images.db)
Example:
# Custom home directory
runtime = boxlite.Boxlite(boxlite.Options(home_dir="/custom/path"))Override default runtime home directory.
Default: ~/.boxlite
Example:
export BOXLITE_HOME=/custom/boxlite
python script.pyEnable debug logging for troubleshooting.
Levels: trace, debug, info, warn, error
Example:
# Debug logging
RUST_LOG=debug python script.py
# Trace logging (very verbose)
RUST_LOG=trace python script.py
# Module-specific logging
RUST_LOG=boxlite::runtime=debug python script.pyOverride temporary directory for BoxLite operations.
Default: System temp directory (/tmp on Linux/macOS)
Example:
export BOXLITE_TMPDIR=/custom/tmp
python script.pyBoxLite uses a centralized error enum with specific variants for different error categories.
Platform or hypervisor not supported.
Cause:
- Running on Windows
- Running on Intel Mac
- KVM not available on Linux
- Hypervisor.framework not available on macOS
Example:
Error: unsupported engine kind
Solution:
- Use supported platform (macOS ARM64, Linux x86_64/ARM64)
- Verify hypervisor availability:
- Linux:
grep -E 'vmx|svm' /proc/cpuinfo - macOS: Ensure macOS 12+ on Apple Silicon
- Linux:
Hypervisor or VM engine error.
Cause:
- KVM module not loaded
- Insufficient permissions for
/dev/kvm - Hypervisor.framework error
- VM creation failed
Example:
Error: engine reported an error: KVM is not available
Solution:
# Linux: Load KVM module
sudo modprobe kvm kvm_intel # or kvm_amd
# Linux: Check /dev/kvm permissions
ls -l /dev/kvm
sudo chmod 666 /dev/kvm
# Linux: Add user to kvm group
sudo usermod -aG kvm $USER
# (logout and login required)Invalid box configuration.
Cause:
- Invalid CPU count (< 1 or > host CPUs)
- Invalid memory size (< 128 or > 65536)
- Invalid paths in volumes
- Invalid port numbers
Example:
Error: configuration error: CPU count must be between 1 and 8
Solution:
- Verify configuration parameters are within valid ranges
- Check file paths exist for volume mounts
- Ensure port numbers are valid (1-65535)
Filesystem or disk operation error.
Cause:
- Disk full (
~/.boxlitepartition) - Permission denied writing to
~/.boxlite - Disk image creation failed
- QCOW2 operation failed
Example:
Error: storage error: No space left on device
Solution:
# Check disk space
df -h ~/.boxlite
# Check permissions
ls -ld ~/.boxlite
chmod 755 ~/.boxlite
# Clean up old boxes
# (manually remove ~/.boxlite/boxes/*)OCI image pull or extraction error.
Cause:
- Network connectivity issues
- Invalid image name or tag
- Registry authentication required
- Image not found in registry
- Corrupted image layers
Example:
Error: images error: failed to pull image: 404 Not Found
Solution:
# Verify image exists
docker pull <image>
# Check network connectivity
ping registry-1.docker.io
# Authenticate for private images
docker login
# Clear image cache if corrupted
rm -rf ~/.boxlite/images/*Host-guest communication error (gRPC over vsock).
Cause:
- Guest agent not responding
- vsock connection failed
- gRPC timeout
- Guest initialization failed
Example:
Error: portal error: connection timeout
Solution:
- Enable debug logging:
RUST_LOG=debug - Check if box is running:
box.info().status - Restart box:
box.stop()and recreate - Report issue with logs if persists
Network configuration or connectivity error.
Cause:
- gvproxy not running or crashed
- Port already in use
- Network backend initialization failed
Example:
Error: network error: bind: address already in use
Solution:
# Check port availability
lsof -i :8080
# Stop conflicting process or use different port
ports=[(8081, 80, "tcp")]
# Verify gvproxy binary exists
ls ~/.boxlite/gvproxy/Command execution error.
Cause:
- Command not found in image
- Command crashed or killed
- Execution timeout
- Streaming I/O error
Example:
Error: Execution error: command not found: python3
Solution:
- Verify command exists in image:
result = await box.exec("which", "python3")
- Check exit code and stderr:
result = await box.exec("command") if result.exit_code != 0: print(f"Failed: {result.stderr}")
Internal BoxLite error.
Cause:
- Unexpected internal state
- I/O error
- JSON parsing error
- Unhandled edge case
Example:
Error: internal error: unexpected state transition
Solution:
- Enable debug logging:
RUST_LOG=debug python script.py - Report issue with full logs to GitHub
- Include BoxLite version, platform, and reproduction steps
Box or resource not found.
Cause:
- Box ID doesn't exist
- Box was removed
- Image not in cache
Example:
Error: box not found: 01JJNH8...
Solution:
- List all boxes:
runtime.list() - Verify box ID is correct
- Create new box if needed
Box or resource already exists.
Cause:
- Duplicate box creation attempt
- Port already forwarded
Example:
Error: already exists: box with this ID exists
Solution:
- Use existing box:
runtime.get(box_id) - Remove existing box:
box.remove() - Use different configuration (e.g., different port)
Box is in wrong state for requested operation.
Cause:
- Executing command on stopped box
- Stopping already stopped box
- Restarting box that never started
Example:
Error: invalid state: cannot execute on stopped box
Solution:
- Check box status:
info = await box.info(); print(info.status) - Restart box if stopped:
runtime.get(box_id)(may auto-restart) - Create new box if needed
import boxlite
async def safe_execution():
try:
async with boxlite.SimpleBox(image="python:slim") as box:
result = await box.exec("python", "script.py")
# Check exit code
if result.exit_code != 0:
print(f"Command failed: {result.stderr}")
return
except Exception as e:
# All BoxLite errors are raised as Python exceptions
print(f"Error: {e}")
# Enable debug logging for details
# RUST_LOG=debug python script.pyuse boxlite::{BoxliteRuntime, BoxliteError, BoxliteResult};
fn main() -> BoxliteResult<()> {
let runtime = BoxliteRuntime::default_runtime();
match runtime.create(options) {
Ok((box_id, litebox)) => {
// Success
}
Err(BoxliteError::UnsupportedEngine) => {
eprintln!("Platform not supported");
return Err(BoxliteError::UnsupportedEngine);
}
Err(BoxliteError::Image(msg)) => {
eprintln!("Image error: {}", msg);
// Handle image-specific error
}
Err(e) => {
eprintln!("Unexpected error: {}", e);
return Err(e);
}
}
Ok(())
}BoxLite uses QCOW2 (QEMU Copy-On-Write version 2) for persistent disks.
Location: ~/.boxlite/boxes/{box-id}/disk.qcow2
Format: QCOW2 (copy-on-write image format)
Features:
- Thin provisioning (sparse allocation)
- Copy-on-write snapshots
- Compression support
Size: Specified by disk_size_gb parameter
Lifecycle:
- Created on first box start (if
disk_size_gbset) - Persists across stop/restart
- Deleted when box is removed
Tools:
# Inspect QCOW2 image
qemu-img info ~/.boxlite/boxes/{box-id}/disk.qcow2
# Convert to raw (if needed)
qemu-img convert -f qcow2 -O raw disk.qcow2 disk.rawBoxLite caches OCI images at the layer level for fast starts.
Location: ~/.boxlite/images/
Structure:
~/.boxlite/images/
├── blobs/
│ └── sha256/
│ ├── abc123... # Layer blob
│ ├── def456... # Layer blob
│ └── ...
└── index.json # Image index
Format: OCI Image Layout Specification
Caching:
- Blob-level deduplication across images
- Shared base layers (e.g.,
python:3.11andpython:3.12share layers) - Automatic garbage collection (future feature)
Clearing Cache:
# Clear all cached images
rm -rf ~/.boxlite/images/*
# Images will be re-pulled on next useBox metadata and state are stored as JSON.
Location: ~/.boxlite/boxes/{box-id}/config.json
Format: JSON
Contents:
- Box ID (ULID)
- Image specification
- Resource limits (CPUs, memory)
- Volume mounts
- Port forwarding
- Environment variables
- Creation timestamp
- Status (running, stopped, etc.)
Example:
{
"id": "01JJNH8...",
"image": "python:slim",
"cpus": 2,
"memory_mib": 1024,
"volumes": [
{
"host_path": "/host/data",
"guest_path": "/mnt/data",
"read_only": true
}
],
"ports": [
{
"host_port": 8080,
"guest_port": 80,
"protocol": "tcp"
}
],
"created_at": "2025-01-15T10:30:00Z",
"status": "running"
}Notes:
- Do not manually edit (managed by BoxLite)
- Used for box persistence and recovery
- Deleted when box is removed
BoxLite uses SQLite for metadata persistence.
Locations:
~/.boxlite/db/boxes.db- Box registry and metadata~/.boxlite/db/images.db- Image cache index
Schema:
- Follows Podman-style pattern: immutable config + mutable state
- Box config stored as JSON blob
- Box state tracked separately
- Image layers indexed by digest
Tools:
# Inspect database
sqlite3 ~/.boxlite/db/boxes.db ".tables"
sqlite3 ~/.boxlite/db/boxes.db "SELECT * FROM boxes;"
# Backup
cp ~/.boxlite/db/boxes.db ~/backup/boxes.db.backupNotes:
- Do not manually modify (data corruption risk)
- Backed up automatically on box operations
- Corruption recovery: Delete and recreate from box config files