Fast microVM execution for development. Run commands in isolated Linux VMs with container image support, shared filesystems, and sub-second boot times.
# Run a command in an Ubuntu VM
yobo run --image docker.io/library/ubuntu:24.04 -- cat /etc/os-release
# Interactive shell
yobo shell --image docker.io/library/ubuntu:24.04
# Persistent VM with workspace mount
yobo start --vm mydev --image ubuntu:24.04 --workspace ~/projects/myapp
yobo shell --vm mydev # connect from another terminal- Fast boot (~100ms) via libkrun/KVM
- OCI image support - pull and run any container image
- Shared filesystems - mount your workspace into the VM
- Rootless operation - no root required (user namespaces)
- Layer deduplication - shared base images across VMs
- eBPF observability - BTF-enabled kernel for tracing
- Linux with KVM support (
/dev/kvmaccessible) - User namespaces enabled
- subuid/subgid configured for your user
Check KVM access:
ls -l /dev/kvm
# If permission denied, add yourself to the kvm group:
sudo usermod -aG kvm $USER
# Then log out and back inCheck subuid/subgid:
grep $USER /etc/subuid /etc/subgid
# Should show something like: cbro:100000:65536
# If missing, add with:
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USERIf someone has provided you with a pre-built yobo binary and libkrunfw.so:
# Install binary
mkdir -p ~/.local/bin ~/.local/lib
cp yobo ~/.local/bin/
mkdir -p ~/.local/lib/yobo
cp libkrun.so* libkrunfw.so* ~/.local/lib/yobo/
# Add to shell profile (~/.bashrc or ~/.zshrc)
export PATH="$HOME/.local/bin:$PATH"
export LD_LIBRARY_PATH="$HOME/.local/lib/yobo:$LD_LIBRARY_PATH"
# Test
yobo run --image alpine:latest -- echo "Hello from VM!"Rust & Go toolchains:
# Rust (1.70+)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Go (1.24+)
# See https://go.dev/doc/installTask (task runner):
# macOS
brew install go-task
# Linux
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/binSystem dependencies (Debian/Ubuntu):
sudo apt install build-essential pkg-config libssl-dev fuse-overlayfsSystem dependencies (Fedora/RHEL):
sudo dnf install gcc make openssl-devel fuse-overlayfs# Build everything (Go init + Rust CLI)
task build
# Outputs:
# - yobo-init-go/yobo-init (Go static binary, embedded in CLI)
# - target/release/yobo (Rust CLI)Or manually:
# Step 1: Build Go init (must be first)
cd yobo-init-go
CGO_ENABLED=0 go build -ldflags="-s -w" -o yobo-init .
cd ..
# Step 2: Build Rust CLI (embeds the Go binary)
cargo build --releaseThe custom kernel adds eBPF/BTF support for observability. This takes ~20-30 minutes.
Additional dependencies (Debian/Ubuntu):
sudo apt install libncurses-dev bison flex libelf-dev bc \
python3 python3-pyelftools dwarves libdw-dev zlib1g-devAdditional dependencies (Fedora/RHEL):
sudo dnf install ncurses-devel bison flex elfutils-libelf-devel bc \
python3 python3-pyelftools dwarves elfutils-devel zlib-develBuild and install:
# Build and install to ~/.local/lib
task libkrunfw-install
# Or manually:
cd libkrunfw
./build.sh installThis builds Linux 6.12 with BTF support and installs libkrunfw.so to ~/.local/lib/.
# Install yobo with bundled libkrunfw to ~/.local/
task install
# Or manually copy:
cp target/release/yobo ~/.local/bin/Add to your shell profile:
export PATH="$HOME/.local/bin:$PATH"
export LD_LIBRARY_PATH="$HOME/.local/lib/yobo:$LD_LIBRARY_PATH"For faster iteration without embedding the init binary:
task build-dev # or: cargo build# Run a command and exit
yobo run --image ubuntu:24.04 -- ls -la /
# With workspace mounted at /workspace
yobo run --image ubuntu:24.04 --workspace . -- ls /workspace# Shell with PTY
yobo shell --image ubuntu:24.04
# With resource limits
yobo shell --image ubuntu:24.04 --cpus 4 --memory 4096# Start a named VM (shows monitoring console)
yobo start --vm mydev --image ubuntu:24.04 --workspace ~/code
# In another terminal, connect to it
yobo shell --vm mydev
yobo run --vm mydev -- make build
# List running VMs
yobo list
# Stop a VM
yobo delete --vm mydev| Flag | Description | Default |
|---|---|---|
--image |
OCI image reference | required |
--workspace |
Host directory to mount at /workspace | none |
--cpus |
Number of vCPUs | 2 |
--memory |
Memory in MB | 2048 |
--vm |
VM name (for persistent VMs) | auto-generated |
┌─────────────────────────────────────────────────────────────────┐
│ Host │
│ ┌─────────────┐ │
│ │ yobo CLI │ │
│ └──────┬──────┘ │
│ │ fork() + user namespace │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ microVM (KVM) │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ yobo-init (PID 1) │ │ │
│ │ │ - Control port 47100 (JSON) │ │ │
│ │ │ - Command port 47101 (binary framing) │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ virtiofs mounts: │ │
│ │ / ← OCI image layers (overlay) │ │
│ │ /workspace ← host workspace directory │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Components:
- yobo CLI (Rust) - VM lifecycle, image pulling, client connections
- libkrun - Lightweight KVM-based VMM (no QEMU dependency)
- yobo-init (Go) - Guest PID 1, command execution, PTY allocation
- fuse-overlayfs - Rootless overlay for OCI layers
See docs/ARCHITECTURE.md for details.
~/.yobo/
├── layers/ # Shared OCI image layers (deduplicated)
│ └── <digest>/ # Unpacked layer directory
└── <vm-name>/
├── .yobo-meta.json # VM configuration
├── upper/ # Overlay upper layer (VM writes)
├── work/ # Overlay work directory
├── merged/ # Overlay merged view (rootfs)
└── vm.info # Running VM info (ports, auth)
~/.cache/yobo/
└── yobo-init # Extracted embedded init binary
task test # All tests (Rust + Go)
task test-rust # Rust tests only
task test-init # Go tests only
task check # cargo check + clippysudo usermod -aG kvm $USER
# Log out and back in# Check subuid/subgid are configured
grep $USER /etc/subuid /etc/subgid
# Add if missing
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER# Ensure library path is set
export LD_LIBRARY_PATH="$HOME/.local/lib/yobo:$LD_LIBRARY_PATH"
# Verify library exists
ls -la ~/.local/lib/yobo/# If a VM didn't clean up properly
fusermount -u ~/.yobo/<vm-name>/merged
rm -rf ~/.yobo/<vm-name>yobo uses custom-built versions of libkrun and libkrunfw with patches for:
- eBPF/BTF support (libkrunfw) - Enables in-guest eBPF programs
- ICMP passthrough (libkrun + libkrunfw) - Makes
pingwork inside VMs
Build scripts are in libkrunfw/ and libkrun/. See docs/ARCHITECTURE.md for details.
MIT