Beta

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.

Every command

Each command's help, exactly as reims-ctl help NAME prints it. Every option takes its value as --name value or --name=value, and yes/no options also take a bare --name for yes. With no command, reims-ctl opens the interactive interface.

reims-ctl help

reims-ctl help
$ reims-ctl help
Create, boot and manage macOS VMs on QEMU with reims-vgpu.

Run with no command for the interactive interface. Every option takes its value as `--name value` or
`--name=value`; yes/no options also take a bare `--name` for yes.

Usage: reims-ctl [COMMAND]

Commands:
  list             List the VMs and whether they run
  create           Create a VM
  delete           Delete a VM (its directory too, unless --keep-files)
  start            Start a VM: a window opens for each of its displays
  stop             Shut a VM down; if the guest has not shut down when the timeout ends, power it
                   off
  show             Show a VM's settings and state
  set              Change a VM's settings (they apply at its next start)
  view             Show a running VM's screen in this terminal, and use its keyboard and mouse from
                   here
  command          Print the QEMU command that runs a VM, as a shell script
  insert           Give a VM (x86-64) an installer image for its next start; a DMG is converted to a
                   raw image in the VM's directory
  eject            Take the installer out of a VM (x86-64)
  update-opencore  Replace a VM's OpenCore image (x86-64) with one the installed reims-util makes,
                   presenting the same Mac
  gpus             List the GPUs a VM can be given (Linux)
  logs             Print the end of a VM's QEMU log, or its serial console's
  report           Zip a VM's logs, settings and the host's details into Downloads, for a bug report
  update           Update reims-ctl and its QEMU from the checkout it was installed from
  doctor           Check the host and the install
  tui              The interactive interface (what reims-ctl runs with no command)
  help             Print this message or the help of the given subcommand(s)

Options:
  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

VMs live in ~/.local/share/reims-ctl/vms unless created elsewhere (--dir); `reims-ctl command NAME`
prints the QEMU command a VM runs, for scripts of your own.

reims-ctl create

Make a VM: from an IPSW or a VM you have on a Mac, from Apple’s installer or a disk you have on Linux.

reims-ctl help create
$ reims-ctl help create
Create a VM

Usage: reims-ctl create [OPTIONS] [NAME]

Arguments:
  [NAME]  The VM's name (or --name)

Options:
      --name <NAME>                The VM's name
      --dir <DIR>                  Its directory (default ~/.local/share/reims-ctl/vms/NAME)
      --cpus <CPUS>                vCPUs
      --memory <MEMORY>            RAM, such as 8G
      --disk-size <DISK_SIZE>      A new disk of this size, such as 128G
      --disk <DISK>                An existing disk image
      --disk-mode <DISK_MODE>      How an existing disk is used: copy (a reflink or clone where it
                                   can) or in-place [default: copy]
      --macos <VERSION>            x86-64: download this macOS from Apple to install: a name
                                   (tahoe), a number (26) or latest; with --offline, also a release
                                   (26.6.2) or a build (25G83)
      --offline                    x86-64: with --macos, an offline installer of one release (13 to
                                   20 GB), which installs with no network, rather than Apple's
                                   recovery image (about 1 GB), which downloads the newest release
                                   as it installs
      --installer <INSTALLER>      x86-64: an installer image of your own, attached as a disk: a raw
                                   image, such as a recovery image's BaseSystem.img, or a DMG,
                                   converted to a raw image in the VM's directory
      --opencore <OPENCORE>        x86-64: an OpenCore image of your own to copy, with OVMF_CODE.fd
                                   and OVMF_VARS.fd beside it (default: a new one made for the VM,
                                   with OVMF and a Mac identity of its own)
      --mac <MAC>                  The network card's MAC
      --ipsw <IPSW>                arm64: install macOS from this IPSW, or `latest` to download the
                                   newest this Mac supports
      --bundle <BUNDLE>            arm64: import a Virtualization.framework VM's directory
                                   (macosvm's or tart's)
      --bundle-mode <BUNDLE_MODE>  arm64: copy (an APFS clone) or in-place [default: copy]
      --ecid <ECID>                arm64: the machine identifier's ECID, where the bundle does not
                                   hold it
      --displays <DISPLAYS>        Displays, 1 to 8, each in a window of its own
      --resolution <RESOLUTION>    The guest's first mode: WIDTHxHEIGHT, or host for the host
                                   screen's modes
      --hidpi [<HIDPI>]            Run the mode HiDPI (3840x2160 looks like 1920x1080) [possible
                                   values: true, false]
      --borderless [<BORDERLESS>]  Borderless windows that fill their screens [possible values:
                                   true, false]
      --refresh <REFRESH>          The refresh rate offered to the guest
      --gpu <GPU>                  The GPU (Linux): auto, a number or name from `reims-ctl gpus`, or
                                   a Vulkan ICD JSON file
      --logs [<LOGS>]              Keep the library's log and the serial console [possible values:
                                   true, false]
      --audio [<AUDIO>]            A USB audio device on the host's sound (on x86-64, also the HDA
                                   controller OpenCore's boot chime plays on) [possible values:
                                   true, false]
      --ssh-port <SSH_PORT>        Forward this port on 127.0.0.1 to the guest's SSH port
      --start                      Start it once made
  -h, --help                       Print help

Examples:
  An x86-64 guest on Linux:

    # Download macOS Tahoe from Apple, make the VM's OpenCore image and a new
    # 128G disk, and start it: the installer boots into macOS Recovery. Once
    # macOS is installed, reims-ctl eject mac takes the installer out
    reims-ctl create mac --macos tahoe --start

    # One exact release, which installs with no network (13 to 20 GB)
    reims-ctl create mac --macos 26.6.2 --offline --start

    # An installer of your own, such as a recovery image (BaseSystem.dmg)
    reims-ctl create mac --installer ~/Downloads/BaseSystem.dmg

    # A disk that already has macOS installed (copied; see --disk-mode), with
    # the OpenCore image it booted from, which keeps its Mac's identity
    reims-ctl create mac --disk ~/vms/mac.qcow2 --opencore ~/vms/OpenCore.qcow2

  An arm64 guest on an Apple silicon Mac:

    # Install the newest macOS this Mac supports, on a new 64G disk
    reims-ctl create mac --ipsw latest --start

    # A macosvm or tart VM that already has macOS installed (an APFS clone)
    reims-ctl create mac --bundle ~/VMs/macos13

reims-ctl start

Start it; a window opens for each display.

reims-ctl help start
$ reims-ctl help start
Start a VM: a window opens for each of its displays

Usage: reims-ctl start <NAME>

Arguments:
  <NAME>  

Options:
  -h, --help  Print help

reims-ctl stop

Ask macOS to shut down, or power off.

reims-ctl help stop
$ reims-ctl help stop
Shut a VM down; if the guest has not shut down when the timeout ends, power it off

Usage: reims-ctl stop [OPTIONS] <NAME>

Arguments:
  <NAME>  

Options:
      --force              Power off at once
      --timeout <TIMEOUT>  Seconds to wait for the guest (the VM's own setting by default)
  -h, --help               Print help

reims-ctl list

Your VMs and whether they run.

reims-ctl help list
$ reims-ctl help list
List the VMs and whether they run

Usage: reims-ctl list [OPTIONS]

Options:
      --json  Machine-readable output
  -h, --help  Print help

reims-ctl show

One VM’s settings and state.

reims-ctl help show
$ reims-ctl help show
Show a VM's settings and state

Usage: reims-ctl show <NAME>

Arguments:
  <NAME>  

Options:
  -h, --help  Print help

reims-ctl set

Change its settings, for its next start.

reims-ctl help set
$ reims-ctl help set
Change a VM's settings (they apply at its next start)

Usage: reims-ctl set [OPTIONS] <NAME>

Arguments:
  <NAME>  

Options:
      --cpus <CPUS>                    
      --memory <MEMORY>                RAM, such as 8G
      --graphics <GRAPHICS>            x86-64: reims-vgpu, or vmware-svga for QEMU's VMware SVGA:
                                       one display with no GPU acceleration, in QEMU's own window
      --displays <DISPLAYS>            
      --resolution <RESOLUTION>        WIDTHxHEIGHT, or host
      --hidpi [<HIDPI>]                [possible values: true, false]
      --borderless [<BORDERLESS>]      [possible values: true, false]
      --refresh <REFRESH>              The refresh rate offered to the guest; 0 for the host
                                       screen's
      --gpu <GPU>                      auto, a number or name from `reims-ctl gpus`, or a Vulkan ICD
                                       JSON file
      --logs [<LOGS>]                  [possible values: true, false]
      --log-level <LOG_LEVEL>          REIMS_VGPU_LOG's filter, such as info or
                                       warn,reims_vgpu_core=debug
      --audio [<AUDIO>]                [possible values: true, false]
      --audio-backend <AUDIO_BACKEND>  coreaudio, pipewire, pa, alsa, none, or auto
      --network [<NETWORK>]            [possible values: true, false]
      --ssh-port <SSH_PORT>            0 for none
      --mac <MAC>                      
      --stop-timeout <STOP_TIMEOUT>    Seconds stop waits for the guest before it powers the VM off
      --extra-args <EXTRA_ARGS>        More QEMU arguments, as one shell-quoted string; empty for
                                       none
      --env <ENV>                      KEY=VALUE for QEMU's environment; KEY= removes it
                                       (repeatable)
  -h, --help                           Print help

reims-ctl delete

Remove it, and its directory unless you keep it.

reims-ctl help delete
$ reims-ctl help delete
Delete a VM (its directory too, unless --keep-files)

Usage: reims-ctl delete [OPTIONS] <NAME>

Arguments:
  <NAME>  

Options:
      --keep-files  Leave the VM's directory where it is
  -y, --yes         Do not ask
  -h, --help        Print help

reims-ctl view

Its screen in this terminal, with your keyboard and mouse.

reims-ctl help view
$ reims-ctl help view
Show a running VM's screen in this terminal, and use its keyboard and mouse from here

Usage: reims-ctl view [OPTIONS] <NAME>

Arguments:
  <NAME>
          

Options:
      --display <DISPLAY>
          The display to show, from 1
          
          [default: 1]

      --fps <FPS>
          The most frames a second
          
          [default: 15]

      --protocol <PROTOCOL>
          How to draw the screen (by default, the best the terminal answers it can show)

          Possible values:
          - kitty:  kitty's graphics protocol (kitty, Ghostty, Konsole)
          - iterm:  iTerm2's inline images (iTerm2, WezTerm)
          - sixel:  Sixel (foot, xterm, Windows Terminal, VS Code with images on)
          - blocks: Half-block characters in 24-bit color, two pixels a cell: any terminal

  -h, --help
          Print help (see a summary with '-h')

For a VM on a host with no screen, to set macOS up before it has screen sharing or remote login. The
screen is drawn with the terminal's graphics (kitty's, iTerm2's or sixel; half-block characters
where it has none), over SSH as well, and the terminal's keys, mouse and pasted text go to the guest
as a US keyboard's and a tablet's.

Ctrl-] disconnects; the VM keeps running. Alt+key is Cmd+key. The Cmd, Opt, Ctrl and Shift buttons
on the top row hold that key for the next key or click.

reims-ctl logs

The end of its QEMU log, or its serial console’s.

reims-ctl help logs
$ reims-ctl help logs
Print the end of a VM's QEMU log, or its serial console's

Usage: reims-ctl logs [OPTIONS] <NAME>

Arguments:
  <NAME>  

Options:
  -n, --lines <LINES>  Lines to print [default: 40]
      --serial         The serial console's log instead
  -h, --help           Print help

reims-ctl report

Its logs, settings and the host’s details, zipped for a bug report.

reims-ctl help report
$ reims-ctl help report
Zip a VM's logs, settings and the host's details into Downloads, for a bug report

Usage: reims-ctl report <NAME>

Arguments:
  <NAME>  

Options:
  -h, --help  Print help

reims-ctl command

The QEMU command it runs, as a shell script.

reims-ctl help command
$ reims-ctl help command
Print the QEMU command that runs a VM, as a shell script

Usage: reims-ctl command [OPTIONS] <NAME>

Arguments:
  <NAME>  

Options:
  -o, --output <OUTPUT>  Write it to this file (executable) instead
  -h, --help             Print help

reims-ctl insert

Give it an installer for its next start.

reims-ctl help insert
$ reims-ctl help insert
Give a VM (x86-64) an installer image for its next start; a DMG is converted to a raw image in the
VM's directory

Usage: reims-ctl insert <NAME> <PATH>

Arguments:
  <NAME>  
  <PATH>  

Options:
  -h, --help  Print help

reims-ctl eject

Take the installer out.

reims-ctl help eject
$ reims-ctl help eject
Take the installer out of a VM (x86-64)

Usage: reims-ctl eject <NAME>

Arguments:
  <NAME>  

Options:
  -h, --help  Print help

reims-ctl update-opencore

A new OpenCore image presenting the same Mac.

reims-ctl help update-opencore
$ reims-ctl help update-opencore
Replace a VM's OpenCore image (x86-64) with one the installed reims-util makes, presenting the same
Mac

Usage: reims-ctl update-opencore [OPTIONS] <NAME>

Arguments:
  <NAME>  

Options:
      --boot-selection [<BOOT_SELECTION>]
          OpenCore's boot picker at each start, to pick Recovery or another disk (default: as the
          old image has it) [possible values: true, false]
  -h, --help
          Print help

An image an older reims-util made lacks what a newer one's carries, such as ReimsVgpu.kext, which
macOS 26 needs for a display wider than 2048 pixels and for GPU-accelerated Chrome. The new image
presents the same Mac (its model, serial number, MLB, UUID and ROM, read from the old image's
config.plist), so macOS sees no new machine, and the VM keeps its OVMF variables, which hold its
boot entries. Its boot selection, OpenCore's picker, is carried over unless --boot-selection gives
it; hidden, OpenCore boots macOS's startup disk at once. Whatever else was changed in the old image
is not carried over. The VM must be stopped; reims-ctl update installs the reims-util this reims-ctl
needs.

reims-ctl gpus

The GPUs a VM can be given.

reims-ctl help gpus
$ reims-ctl help gpus
List the GPUs a VM can be given (Linux)

Usage: reims-ctl gpus

Options:
  -h, --help  Print help

reims-ctl update

Pull your checkout and install again.

reims-ctl help update
$ reims-ctl help update
Update reims-ctl and its QEMU from the checkout it was installed from

Usage: reims-ctl update [OPTIONS]

Options:
      --channel <CHANNEL>
          Switch the checkout to this channel first; later updates stay on it

          Possible values:
          - stable:      The master branch
          - development: The development branch, which gets changes before stable

  -h, --help
          Print help (see a summary with '-h')

reims-ctl doctor

Check the host and the install.

reims-ctl help doctor
$ reims-ctl help doctor
Check the host and the install

Usage: reims-ctl doctor

Options:
  -h, --help  Print help