How well it runs can still depend on your host and its GPU. Metal, macOS are trademarks of Apple Inc. Reims vGPU is an independent project and is not affiliated with, sponsored by, or endorsed by Apple Inc.
The interactive interface
Run reims-ctl with no command. It lists your VMs, shows the selected one's details, and gives every action a key. It runs in any terminal, over SSH too, and takes the mouse. Each VM's state is read every second, so VMs started or stopped from the shell, a script, or by closing a window show as they are.
Frame by frame
Each tab is the key that opens the frame; each frame is reims-ctl running, captured from a terminal 100 columns wide.
reims-ctl the list
reims-ctl macOS on arm64 · arm64 macOS guest (vmapple, HVF) · QEMU 11.1.50
┌ VMs ──────────────────────────────────────┐┌ macos-26 ───────────────────────────────────────────┐
│ NAME STATE CPUS MEMORY ││state running (pid 38201) │
│› macos-26 running 4 8G ││kind arm64 macOS guest (vmapple, HVF) │
│ macos-27 stopped 4 8G ││directory ~/.local/share/reims-ctl/vms/macos-26 │
│ ││cpus 4 │
│ ││memory 8G │
│ ││disk disk.img (raw) │
│ ││displays 1 x 1920x1080 │
│ ││ecid 11400282047089759542 │
│ ││audio on │
│ ││network user, mac 52:54:00:b7:2b:36 │
│ ││logs on (info) │
│ ││stop timeout 90 s │
│ ││ │
│ ││v shows its screen here, in the terminal │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└───────────────────────────────────────────┘└─────────────────────────────────────────────────────┘
n new Enter menu s start x stop u update ? helpEvery VM and whether it runs, with the selected one’s details beside it. Choose one with ↑ ↓, j k, or a click.
Enter its menu
reims-ctl macOS on arm64 · arm64 macOS guest (vmapple, HVF) · QEMU 11.1.50
┌ VMs ──────────────────────────────────────┐┌ macos-26 ───────────────────────────────────────────┐
│ NAME STATE CPUS MEMORY ││state running (pid 38201) │
│› macos-26 running 4 8G ││kind arm64 macOS guest (vmapple, HVF) │
│ ┌ macos-26 ───────────────────┐ 8G ││directory ~/.local/share/reims-ctl/vms/macos-26 │
│ │ View screen in terminal v │ ││cpus 4 │
│ │ Stop x │ ││memory 8G │
│ │ Power off… K │ ││disk disk.img (raw) │
│ │ Edit settings… e │ ││displays 1 x 1920x1080 │
│ │ Show QEMU command c │ ││ecid 11400282047089759542 │
│ │ Turn logs off l │ ││audio on │
│ │ View logs L │ ││network user, mac 52:54:00:b7:2b:36 │
│ │ Write a bug report b │ ││logs on (info) │
│ └─────────────────────────────┘ ││stop timeout 90 s │
│ ││ │
│ ││v shows its screen here, in the terminal │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└───────────────────────────────────────────┘└─────────────────────────────────────────────────────┘
n new Enter menu s start x stop u update ? helpEnter, or a right click on a VM, opens what can be done with it now, each with its key. This one runs, so it offers its screen, stop and power off.
Ctrl + Enter every command
reims-ctl macOS on arm64 · arm64 macOS guest (vmapple, HVF) · QEMU 11.1.50
┌ VMs ──────────────────────────────────────┐┌ macos-26 ───────────────────────────────────────────┐
│ NAME STATE CPUS MEMORY ││state running (pid 38201) │
│› macos-26 running 4 8G ││kind arm64 macOS guest (vmapple, HVF) │
│ maco┌ macos-26 ──────────────────────┐ ││directory ~/.local/share/reims-ctl/vms/macos-26 │
│ │ Start s │ ││cpus 4 │
│ │ View screen in terminal v │ ││memory 8G │
│ │ Stop x │ ││disk disk.img (raw) │
│ │ Power off… K │ ││displays 1 x 1920x1080 │
│ │ Edit settings… e │ ││ecid 11400282047089759542 │
│ │ Show QEMU command c │ ││audio on │
│ │ Turn logs off l │ ││network user, mac 52:54:00:b7:2b:36 │
│ │ View logs L │ ││logs on (info) │
│ │ Write a bug report b │ ││stop timeout 90 s │
│ │ Make a new OpenCore image… U │ ││ │
│ │ Delete… d │ ││v shows its screen here, in the terminal │
│ └────────────────────────────────┘ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└───────────────────────────────────────────┘└─────────────────────────────────────────────────────┘
n new Enter menu s start x stop u update ? helpHold Ctrl as you press Enter or right-click, and the menu lists every command, whether it can run now or not (Ctrl-Enter needs a terminal that tells it apart from Enter, such as kitty, foot or Ghostty).
n new VM
reims-ctl macOS on arm64 · arm64 macOS guest (vmapple, HVF) · QEMU 11.1.50
┌ VMs ──────────────────────────────────────┐┌ macos-26 ───────────────────────────────────────────┐
│ NAME STATE CPUS MEMORY ││state running (pid 38201) │
│› macos-26 running 4 8G ││kind arm64 macOS guest (vmapple, HVF) │
│ macos-27 stopped 4 8G ││directory ~/.local/share/reims-ctl/vms/macos-26 │
│ ┌ New VM ──────────────────────────────────────────────────────────────────────────────────────┐ │
│ │› Name │ │
│ │ macOS from Install from an IPSW │ │
│ │ IPSW latest │ │
│ │ Disk size 64G │ │
│ │ Storage directory ~/.local/share/reims-ctl/vms/<name> │ │
│ │ CPU cores 8 │ │
│ │ Memory 16G │ │
│ │ Displays 1 │ │
│ │ Resolution 1920x1080 │ │
│ │ HiDPI [ ] no │ │
│ │ Logs [ ] no │ │
│ │ SSH port optional │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │Letters, digits, '-', '_' and '.'. │ │
│ │ │ │
│ └ Enter next · Ctrl-S create · Esc cancel ─────────────────────────────────────────────────────┘ │
│ ││ │
│ ││ │
└───────────────────────────────────────────┘└─────────────────────────────────────────────────────┘
n new Enter menu s start x stop u update ? helpA new VM. On a Mac it installs from an IPSW (latest by default); on Linux you pick a macOS version and reims-ctl downloads its installer from Apple. The form stays open until the VM is made.
e settings
reims-ctl macOS on arm64 · arm64 macOS guest (vmapple, HVF) · QEMU 11.1.50
┌ VMs ──────────────────────────────────────┐┌ macos-26 ───────────────────────────────────────────┐
│ NAME STATE CPUS MEMORY ││state running (pid 38201) │
│› macos-26 running 4 8G ││kind arm64 macOS guest (vmapple, HVF) │
│ ┌ Edit macos-26 (applies at its next start) ───────────────────────────────────────────────────┐ │
│ │› CPU cores 4 │ │
│ │ Memory 8G │ │
│ │ Displays 1 │ │
│ │ Resolution 1920x1080 │ │
│ │ HiDPI [ ] no │ │
│ │ Borderless [ ] no │ │
│ │ Refresh rate the host screen's │ │
│ │ Audio [x] yes │ │
│ │ Logs [x] yes │ │
│ │ Log level info │ │
│ │ Network [x] yes │ │
│ │ SSH port none │ │
│ │ Shutdown timeout 90 │ │
│ │ Extra QEMU args none │ │
│ │ Extra environment none │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │vCPUs; this host has 16. │ │
│ │ │ │
│ └ Enter next · Ctrl-S save · Esc cancel ───────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────┘└─────────────────────────────────────────────────────┘
n new Enter menu s start x stop u update ? helpIts settings: CPUs, memory, displays, resolution, HiDPI, borderless, audio, logs, network, extra QEMU arguments. They apply at its next start.
c QEMU command
macos-26: the QEMU command (w write launch.sh · y copy · Esc close)
#!/bin/sh
# macos-26: the QEMU command reims-ctl 0.1.0 runs for this VM.
# Its window opens under -display none; QMP is at the -qmp socket.
unset REIMS_VGPU_WINDOW
export REIMS_VGPU_LOG=info
exec ~/.local/share/reims-ctl/qemu/current/bin/qemu-system-aarch64 \
-name macos-26 \
-accel 'hvf,kernel-irqchip=on' \
-M 'vmapple,uuid=11400282047089759542' \
-m 8192M \
-smp 4 \
-bios /System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin \
-drive 'file=~/.local/share/reims-ctl/vms/macos-26/aux.img.trimmed,if=pflash,forma
t=raw' \
-drive 'file=~/.local/share/reims-ctl/vms/macos-26/disk.img,if=pflash,format=raw'
\
-drive 'file=~/.local/share/reims-ctl/vms/macos-26/aux.img.trimmed,if=none,id=aux,
format=raw' \
-drive 'file=~/.local/share/reims-ctl/vms/macos-26/disk.img,if=none,id=root,format
=raw' \
-device 'vmapple-virtio-blk-pci,variant=aux,drive=aux' \
-device 'vmapple-virtio-blk-pci,variant=root,drive=root' \
-netdev 'user,id=net0,ipv6=off' \
-device 'virtio-net-pci,netdev=net0,mac=52:54:00:b7:2b:36' \
-global 'apple-gfx-mmio.displays=1' \
-global 'apple-gfx-mmio.resolution=1920x1080' \
-audiodev 'coreaudio,id=snd0' \
-device 'usb-audio,id=audio,audiodev=snd0' \The exact QEMU command it runs: w writes it as launch.sh, y copies it, to run it yourself without reims-ctl.
? every key
help (Esc close)
reims-ctl runs macOS VMs on QEMU with reims-vgpu: each VM's displays open in windows of their own.
↑ ↓ / j k choose a VM, or click it
Enter open its menu: what can be done with it now, each with its key. A right
click on a VM opens its menu too. Hold Ctrl as you press Enter or right click
for a menu of everything, whether it can be done now or not (Ctrl-Enter needs
a terminal that tells it from Enter, such as kitty, foot or Ghostty on a Mac)
n create a VM. On Linux, choose a macOS version: reims-ctl downloads its
installer from Apple and makes the VM's OpenCore image and disk, and the VM
boots into the installer; its details then say how to install macOS. The form
stays open until the VM is made, and shows what failed, to fix and create again;
Esc closes it meanwhile, and it opens again if the create fails
s start it
x stop it: the guest is asked to shut down, and powered off if it has not
when its shutdown timeout ends (edit e to change it)
K kill it: power it off at once
e edit its settings: CPUs, memory, displays, resolution, HiDPI, borderless,
GPU, audio, network, logs, extra QEMU arguments (they apply at its next start),
and on x86-64 its installer image, its boot selection (OpenCore's picker, which
makes it a new OpenCore image) and graphics: reims-vgpu, or QEMU's VMware SVGA,
one display with no GPU acceleration, in QEMU's own window
c show the QEMU command it runs, to write as launch.sh (w) or copy (y):
run it yourself, without reims-ctl
v show a running VM's screen here, in the terminal, and use its keyboard and
mouse from here: for a host with no screen, over SSH too. Ctrl-] comes back
l turn its logs on or off
L view its QEMU log in less: :n shows the serial console, / searches,
F follows the log as it grows, q comes back
b write a bug report: its logs, settings, command and this host's details,
zipped into your Downloads folder
d delete it
U make it a new OpenCore image (x86-64) with the installed reims-util, presenting
the same Mac: an older image lacks ReimsVgpu.kext, which macOS 26 needs for
displays wider than 2048 pixels and GPU-accelerated Chrome
u update reims-ctl and QEMU from your reims-vgpu checkout
r reload the list
? this help
q quit; running VMs keep running
The main screen takes the mouse: to select text on it, hold Shift as you drag (Option in
iTerm2; in Terminal, ⌘R turns its mouse reporting off and on).
The same from a shell: reims-ctl help.Every key, and what it does. The same commands from a shell: reims-ctl help.
Menus: Enter, and Ctrl for everything
You don't need to remember keys. Enter on a VM, or a right click on it, opens a menu of what can be done with it right now, each item with its key. A running VM offers its screen, stop and power off; a stopped one offers start.
Hold Ctrl as you press Enter or right-click and the menu lists every command, whether it can run now or not, so you can see what exists. Telling Ctrl-Enter from Enter takes a terminal that reports keys in detail, such as kitty, foot or Ghostty on a Mac; Ctrl with a right click works everywhere the mouse does.
Forms
n and e open forms. Enter moves to the next field, and the line under the fields explains the one you're on. Ctrl-S creates or saves, Esc cancels. Slow work, like a create, runs in the background and shows its progress in the list; the form stays open until it succeeds and shows any failure, so you can fix the field and submit again.
Every key
| Key | What it does |
|---|---|
| ↑ ↓ or j k | Choose a VM, or click it. |
| Enter | Open the VM’s menu: what can be done with it now, each with its key. A right click on a VM opens it too. |
| Ctrl + Enter | A menu of every command, whether it can run now or not. Ctrl with a right click does the same. Ctrl-Enter needs a terminal that tells it apart from Enter, such as kitty, foot or Ghostty on a Mac. |
| n | Create a VM. The form stays open until the VM is made, and shows what failed to fix and create again; Esc closes it meanwhile, and it opens again if the create fails. |
| s | Start it. |
| x | Stop it: macOS is asked to shut down, and the VM is powered off if it hasn’t by its stop timeout. |
| K | Kill it: power it off at once. |
| e | Edit its settings: CPUs, memory, displays, resolution, HiDPI, borderless, GPU, audio, network, logs, extra QEMU arguments. On x86-64 also its installer image, its boot selection and its graphics. They apply at its next start. |
| c | Show the QEMU command it runs, to write as launch.sh (w) or copy (y). |
| v | Show a running VM’s screen in the terminal, and use its keyboard and mouse from here. Ctrl-] comes back. |
| l | Turn its logs on or off. |
| L | View its QEMU log in less: :n shows the serial console, / searches, F follows the log, q comes back. |
| b | Write a bug report: its logs, settings, command and the host’s details, zipped into Downloads. |
| d | Delete it. |
| U | Make it a new OpenCore image (x86-64) presenting the same Mac. |
| u | Update reims-ctl and QEMU from your checkout. |
| r | Reload the list. |
| ? | Every key. |
| q | Quit; running VMs keep running. |
Selecting text
The main screen takes the mouse, so to select text on it, hold Shift as you drag; in iTerm2 it's Option, and in macOS's Terminal ⌘R turns its mouse reporting off and on.