A Docker-like CLI for saving, sharing, and launching QEMU virtual machines.
Vex turns complex qemu-system-* invocations into named configurations you
can save, edit, distribute, and run by name. It targets embedded development,
firmware development, and OS development workflows where the same handful of
QEMU recipes get typed (and mistyped) every day.
Features
Capability
Commands
Phase
Local config management
save, list, print, rm, rename, edit, exec
1
Shell completions
completions
1
Git remote distribution
push, pull
2
Resource binding
save --image/--firmware/--resource, resource
3
Resource cache
cache
3
Vex Hub (HTTP read-only client)
hub
3
Interactive TUI
tui
4
Installation
Install the vex binary into ~/.cargo/bin (already on PATH for a
standard Rust setup):
cargo install --path .
vex tui
Or build without installing — the binary lands at target/release/vex:
cargo build --release
Requires Rust 1.85+ (edition 2024).
Quickstart
Local — save and run:
vex save my-vm qemu-system-x86_64 -m 2G -smp 4
vex list
vex exec my-vm
Team — push to a Git registry, pull elsewhere:
# Publisher: create a config, then push it
export VEX_REMOTE_URL=git@github.com:my-team/vex-registry.git
vex save dev-box qemu-system-aarch64 -m 4G
vex push team/dev-box:v1 dev-box
# Teammate: pull and run
export VEX_REMOTE_URL=git@github.com:my-team/vex-registry.git
vex pull team/dev-box:v1
vex exec dev-box
Two-pane Browse mode for navigating and launching saved configurations,
in-place e / n Edit mode with a Snippets drawer, and a full-screen
Library mode (Ctrl+L) for managing the user snippet library. Builtin
snippets are read-only; user overrides persist atomically to
~/.vex/snippets.json.
Full keybindings, workflows, and screenshots:
docs/TUI.md.
Resource binding
A configuration’s args may reference external files (disk images, firmware
blobs, …) declared as resources. Resources are bound by key, validated
on save, and substituted into args at exec time using ${res:KEY}.
vex save vm1 qemu-system-x86_64 \
--image disk=./ubuntu.qcow2 \
-m 2G \
-drive 'file=${res:disk},format=qcow2'
vex resource list vm1
vex exec vm1
${res:KEY} placeholders only match keys matching [A-Za-z_][A-Za-z0-9_]*;
other forms are left as literal text. Unknown keys at exec time raise
UnknownResourceReference. By default, vex save captures sha256 + size;
add --no-checksum to skip when files are large or absent locally.
Resource cache
vex pull --fetch-resources and vex hub install --fetch-resources write
downloaded files into a unified content-addressed cache at
<config_dir parent>/resources (default: ~/.vex/resources).
vex cache list
vex cache info <hash-or-prefix>
vex cache rm <hash> [--force]
vex cache prune [--dry-run]
Hash arguments accept the full 64 hex characters or any prefix of at least
4 characters. Override the cache location with VEX_RESOURCE_CACHE_DIR.
Vex Hub
The Vex Hub is a read-only HTTP service that distributes curated
configurations and resource metadata. It serves the same PublishedConfig
v2 format that vex push writes to a Git remote — Git remotes and the Hub
are complementary, not competing.
vex hub list --kind demo
vex hub search arm64
vex hub info team/demo-arm64:v1
vex hub install team/demo-arm64:v1 --as my-arm --fetch-resources
Note: There is no officially deployed Hub server yet. The default
VEX_HUB_URL (hub.vex.example) uses the RFC 2606 reserved TLD and is
intentionally non-resolvable. To use vex hub, point VEX_HUB_URL at
a server that implements the protocol above.
Environment variables
Variable
Purpose
Default
VEX_CONFIG_DIR
Local config storage directory
~/.vex/configs
VEX_REMOTE_URL
Git remote registry URL or local path
(none, push/pull errors out)
VEX_REMOTE_BRANCH
Branch used for remote distribution
main
VEX_REMOTE_GIT_NAME
Git author name for vex push commits
Vex CLI
VEX_REMOTE_GIT_EMAIL
Git author email for vex push commits
vex@example.invalid
VEX_RESOURCE_CACHE_DIR
Resource cache directory
<config_dir parent>/resources
VEX_HUB_URL
Vex Hub base URL
https://hub.vex.example/ (placeholder)
Configuration file format
Each saved configuration is a JSON file at <VEX_CONFIG_DIR>/<name>.json.
The schema is the QemuConfig struct in
src/config/types.rs:
Vex
A Docker-like CLI for saving, sharing, and launching QEMU virtual machines.
Vex turns complex
qemu-system-*invocations into named configurations you can save, edit, distribute, and run by name. It targets embedded development, firmware development, and OS development workflows where the same handful of QEMU recipes get typed (and mistyped) every day.Features
save,list,print,rm,rename,edit,execcompletionspush,pullsave --image/--firmware/--resource,resourcecachehubtuiInstallation
Install the
vexbinary into~/.cargo/bin(already onPATHfor a standard Rust setup):Or build without installing — the binary lands at
target/release/vex:Requires Rust 1.85+ (edition 2024).
Quickstart
Local — save and run:
Team — push to a Git registry, pull elsewhere:
Public — install from a Vex Hub (see Vex Hub):
Interactive TUI
Two-pane Browse mode for navigating and launching saved configurations, in-place
e/nEdit mode with a Snippets drawer, and a full-screen Library mode (Ctrl+L) for managing the user snippet library. Builtin snippets are read-only; user overrides persist atomically to~/.vex/snippets.json.Full keybindings, workflows, and screenshots: docs/TUI.md.
Resource binding
A configuration’s
argsmay reference external files (disk images, firmware blobs, …) declared as resources. Resources are bound by key, validated on save, and substituted into args at exec time using${res:KEY}.${res:KEY}placeholders only match keys matching[A-Za-z_][A-Za-z0-9_]*; other forms are left as literal text. Unknown keys atexectime raiseUnknownResourceReference. By default,vex savecaptures sha256 + size; add--no-checksumto skip when files are large or absent locally.Resource cache
vex pull --fetch-resourcesandvex hub install --fetch-resourceswrite downloaded files into a unified content-addressed cache at<config_dir parent>/resources(default:~/.vex/resources).Hash arguments accept the full 64 hex characters or any prefix of at least 4 characters. Override the cache location with
VEX_RESOURCE_CACHE_DIR.Vex Hub
The Vex Hub is a read-only HTTP service that distributes curated configurations and resource metadata. It serves the same
PublishedConfigv2 format thatvex pushwrites to a Git remote — Git remotes and the Hub are complementary, not competing.Protocol: docs/HUB_PROTOCOL.md.
Environment variables
VEX_CONFIG_DIR~/.vex/configsVEX_REMOTE_URLVEX_REMOTE_BRANCHmainVEX_REMOTE_GIT_NAMEvex pushcommitsVex CLIVEX_REMOTE_GIT_EMAILvex pushcommitsvex@example.invalidVEX_RESOURCE_CACHE_DIR<config_dir parent>/resourcesVEX_HUB_URLhttps://hub.vex.example/(placeholder)Configuration file format
Each saved configuration is a JSON file at
<VEX_CONFIG_DIR>/<name>.json. The schema is theQemuConfigstruct insrc/config/types.rs:desc,qemu_version,resources, and the optional fields inside eachResourceRefare omitted from output when unset.Documentation
Roadmap
PublishedConfigv1.PublishedConfigv2.License
See LICENSE.