I’m building a menu bar app for macOS. It works perfectly on my Mac. Now I need to know if it works on a clean macOS: without my settings, without my permissions, without my data. A user installing it from scratch.
How do you test that? You need a virtual machine.
“Easy,” I thought. “I have UTM installed. I’ll open the wizard, create a macOS VM, and we’re good to go.”
It wasn’t going to be that easy.
UTM: beautiful but untameable
UTM is an excellent application. Polished interface, support for macOS as a guest on Apple Silicon, full screen, shared clipboard. For manual use, it’s great.
The problem comes when you try to automate it.
UTM has a CLI called utmctl. It can list VMs, start them, stop them, clone them. What it can’t do is create a VM. And for macOS guest, not even UTM’s AppleScript allows creating them — the operating system field is hardcoded to Linux.
In plain language: if you want a macOS VM in UTM, you create it manually through the wizard. Every time. With its clicks, its IPSW download (the macOS installation image for Apple Silicon — the equivalent of a traditional ISO, but packaged by Apple), its installation wait time.
For a dev who needs to spin up and destroy VMs as part of a QA workflow, that’s a pain in the ass.
Tart: macOS VMs for the rest of us
Tart is what happens when someone designs a virtualization tool thinking about developers instead of end users.
It uses exactly the same Apple Virtualization.framework that UTM does. Same technology, same capabilities, same native speed. The difference is the interface: Tart is CLI-first.
| |
That’s it. No configuration GUI, no wizard. A binary in your PATH.
One command to rule them all
Create a macOS VM with the latest available version:
| |
That’s all. latest tells Tart “give me the latest version of macOS this Mac supports.” Tart queries Apple’s API, downloads the IPSW (~15 GB — yes, macOS is hefty), creates the virtual disk, installs the operating system and leaves you with a VM ready to boot. Go grab a latte, because it takes a while — but you don’t need to touch anything.
Start the VM:
| |
A window opens with the macOS desktop. Mouse, keyboard, screen. Exactly like UTM, but launched from a tart run.
Shared folder: the detail that makes the difference
This is where Tart won me over. I need to copy my app from the host Mac to the VM. In UTM you have to manually configure VirtioFS, mount it from the guest terminal, and pray that the config.plist doesn’t get corrupted (there are known bugs).
In Tart:
| |
Inside the VM, the folder appears at /Volumes/My Shared Files/shared. You drag the app to /Applications and you’re done. No configuration, no mounting.
My actual QA workflow
This is what I do to test my app on a clean macOS:
| |
Inside the VM:
- Open
/Volumes/My Shared Files/build/ - Drag
Tokamak.appto/Applications/ - Run and verify: login, permissions, sandbox, menu bar, notifications
If I need to start from scratch (test the first launch experience):
| |
Destroy and recreate. No questions, no confirmations, no wizard.
Configure resources
By default Tart assigns reasonable resources, but you can adjust them:
| |
What Tart doesn’t have (and why it doesn’t matter)
It doesn’t have a management GUI with thumbnails of each VM. It doesn’t have drag and drop for ISOs. It doesn’t have a pretty “New VM” button.
If what you need is a desktop app to manage VMs, use UTM. It’s fantastic for that.
But if what you need is to test your app on a clean macOS, destroy the VM, recreate it, share a folder, and do all that from a script or a Makefile… UTM can’t. Tart can.
The complete recipe
| |
The documentation fits in a README. The learning curve fits in a latte. If you’re developing for macOS and not using Tart, you’re making things harder than necessary.