Skip to main content
vee
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Installation

There are two ways to install vee:

  1. Download a prebuilt binary from the GitHub Releases page (fastest — no Go toolchain needed).
  2. Build from source (requires Go 1.21 or later).

Either way, vee drives QEMU, so the host QEMU packages listed under Prerequisites must be installed first.

Download a prebuilt binary

Prebuilt vee binaries are published for every supported host on the Releases page. Each release ships a .tar.gz per platform plus a matching .sha256 checksum file:

PlatformAsset
Linux (x86-64)vee-linux-amd64.tar.gz
Linux (ARM64)vee-linux-arm64.tar.gz
macOS (Apple Silicon)vee-darwin-arm64.tar.gz
macOS (Intel)vee-darwin-amd64.tar.gz
Windows (x86-64)vee-windows-amd64.tar.gz

Each snippet below grabs the latest release. For a specific version, swap latest/download for download/<tag> (e.g. download/v0.2.0), and pick the matching asset from the table above.

Linux

curl -LO https://github.com/Benehiko/vee/releases/latest/download/vee-linux-amd64.tar.gz
curl -LO https://github.com/Benehiko/vee/releases/latest/download/vee-linux-amd64.tar.gz.sha256
sha256sum -c vee-linux-amd64.tar.gz.sha256
tar xzf vee-linux-amd64.tar.gz
install -Dm755 vee "$HOME/.vee/bin/vee"

macOS

curl -LO https://github.com/Benehiko/vee/releases/latest/download/vee-darwin-arm64.tar.gz
curl -LO https://github.com/Benehiko/vee/releases/latest/download/vee-darwin-arm64.tar.gz.sha256
shasum -a 256 -c vee-darwin-arm64.tar.gz.sha256
tar xzf vee-darwin-arm64.tar.gz
mkdir -p "$HOME/.vee/bin"   # stock BSD install(1) has no GNU -D
install -m755 vee "$HOME/.vee/bin/vee"
xattr -d com.apple.quarantine "$HOME/.vee/bin/vee" 2>/dev/null || true   # unsigned binary

# Apple Silicon only: the same tarball carries the macOS-guest helper.
if [ -f vee-vz-helper ]; then
  install -m755 vee-vz-helper "$HOME/.vee/bin/vee-vz-helper"
  xattr -d com.apple.quarantine "$HOME/.vee/bin/vee-vz-helper" 2>/dev/null || true
fi

macOS guests: vee-vz-helper

The darwin-arm64 tarball contains a second binary, vee-vz-helper, which hosts macOS guests on Apple’s Virtualization.framework — one helper process per running guest, the way qemu-system backs a QEMU VM. You only need it for vee create --template macos; every other guest runs on QEMU and ignores it.

Install it in the same directory as vee, as the snippet above does. vee looks for it under $VEE_VZ_HELPER first, then beside the running vee binary, then in ~/.vee/bin, then on your PATH. It is ad-hoc codesigned with the com.apple.security.virtualization entitlement, which macOS honours without a paid Apple Developer account; a browser download arrives quarantined, and vee clears that flag itself whenever it resolves the helper. From a source checkout on an Apple Silicon Mac, make install builds, signs and installs it alongside vee (make vz-helper does the helper alone).

See macOS guests for what that backend supports.

Windows (PowerShell)

$Base = "https://github.com/Benehiko/vee/releases/latest/download"
iwr "$Base/vee-windows-amd64.tar.gz"        -OutFile vee.tar.gz
iwr "$Base/vee-windows-amd64.tar.gz.sha256" -OutFile vee.tar.gz.sha256

# Verify the checksum:
if ((Get-Content vee.tar.gz.sha256).Split()[0].ToLower() -ne (Get-FileHash vee.tar.gz -Algorithm SHA256).Hash.ToLower()) { throw "checksum mismatch" }

tar xzf vee.tar.gz   # tar ships with Windows 10+
New-Item -ItemType Directory -Force "$HOME\.vee\bin" | Out-Null
Move-Item -Force vee.exe "$HOME\.vee\bin\vee.exe"

Then add ~/.vee/bin to your PATH (next section) and jump to Verify. If you plan to run VMs on boot, see Run vee as a daemon.

Prerequisites

Install the required system packages before building.

Note
Managed QEMU. For platforms where vee publishes a vee-qemu bundle, vee downloads a pinned, checksum-verified QEMU into ~/.vee/bin/ on first use and prefers it over any system QEMU. That bundle also carries the edk2/OVMF firmware under ~/.vee/share/qemu/, so neither QEMU nor OVMF needs a system install. When no bundle is published for your platform, vee falls back to the system QEMU on your PATH — install the packages below.

Arch Linux

sudo pacman -S qemu-desktop edk2-ovmf openssh virtiofsd swtpm

Ubuntu / Debian

sudo apt install qemu-system-x86 ovmf openssh-client virtiofsd swtpm

Fedora

sudo dnf install qemu-kvm edk2-ovmf openssh-clients virtiofsd swtpm
PackagePurpose
qemu-system-x86_64VM execution engine
qemu-imgDisk image creation
ovmfUEFI firmware
opensshvee ssh and vee tunnel
virtiofsdHost directory sharing into VMs — optional, see below
swtpmTPM 2.0 emulation (Windows template, x86_64 hosts — arm64 Windows guests attach no TPM)
Note

OVMF firmware location. Distros ship OVMF under different names and directories — Arch puts it in /usr/share/OVMF/x64/OVMF_*.4m.fd, Debian/Ubuntu/Mint in /usr/share/OVMF/OVMF_*_4M.fd, Fedora/RHEL in /usr/share/edk2/ovmf/. vee probes all of these automatically, so installing your distro’s OVMF package (ovmf on Debian-family, edk2-ovmf on Arch/Fedora) is all that’s needed. If your firmware lives somewhere unusual, override ovmf_code_path / ovmf_vars_path in ~/.vee/config.yaml.

When vee uses a managed QEMU bundle (see the note above), that bundle ships edk2/OVMF firmware under ~/.vee/share/qemu/, which vee prefers over any system OVMF — so no distro OVMF package is required in that case.

Note
virtiofsd is optional. When a VM first requests a virtiofs share and no system virtiofsd is found, vee builds a pinned, checksum-verified copy on demand into ~/.vee/bin/virtiofsd — inside a host container (nerdctl/docker) if one is available, otherwise inside a temporary Ubuntu VM. Installing the distro package skips this on-demand build.

KVM access

Your user must be in the kvm group to run hardware-accelerated VMs:

sudo usermod -aG kvm $USER

Log out and back in (or newgrp kvm) for the change to take effect.

Build and install

git clone https://github.com/Benehiko/vee.git
cd vee
make install

This builds the binary and installs it to ~/.vee/bin/vee. Add that directory to your PATH:

echo 'export PATH="$HOME/.vee/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Shell completion

# bash — add to ~/.bashrc
source <(vee completion bash)

# zsh — add to ~/.zshrc
source <(vee completion zsh)

# fish — add to ~/.config/fish/config.fish
vee completion fish | source

Verify

vee --help

Run vee as a daemon

The daemon starts every VM marked autostart=true on boot, restarts any that exit, and stops running VMs cleanly when the host shuts down. It is supported on Linux and macOS; install it with (prompts for sudo):

vee daemon install

Linux (systemd)

The daemon runs as a systemd system service (/etc/systemd/system/vee.service) so it can react to logind’s shutdown signal in time to stop VMs cleanly.

Check status, logs, and control the service with the usual systemctl verbs:

systemctl status vee            # is it running?
journalctl -u vee -f            # follow logs
sudo systemctl restart vee      # restart (e.g. after upgrading the vee binary)
sudo systemctl stop vee         # stop

macOS (launchd)

The daemon runs as a system-level launchd LaunchDaemon (/Library/LaunchDaemons/io.vee.daemon.plist) under your user account. At host shutdown, launchd’s SIGTERM gives it up to 300 seconds to power off every running VM.

sudo launchctl print system/io.vee.daemon        # is it running?
tail -F ~/.vee/logs/daemon.log                   # daemon stdout/stderr
sudo launchctl kickstart -k system/io.vee.daemon # restart (e.g. after upgrading vee)

Note that unloading the job (launchctl bootout, or vee daemon uninstall) also stops running VMs gracefully — macOS gives launchd jobs no way to tell a plain unload apart from a host shutdown.

Note
After upgrading vee, restart the daemon so it runs the new binary: sudo systemctl restart vee (Linux) or sudo launchctl kickstart -k system/io.vee.daemon (macOS). The service’s executable path is pinned to the absolute path of the vee binary that ran vee daemon install. If your upgrade replaces that same file in place (a new release extracted over ~/.vee/bin/vee, or make install), a restart is all you need. If the new binary lands at a different path, re-run vee daemon install so the service points at it.

Remove the service with:

vee daemon uninstall