A virtual machine (VM) is a persistent Linux computer of your own that runs on this machine, for you and your agents to work in. It has its own disk, its own private address and a user who may do anything inside it. VMs are what exe exists for: the rest of the desktop is there to make them, work in them and show what runs in them.
For you:
dev) has passwordless sudo, and the VM is the sandbox boundary: you may install and run anything in it.ssh, scp and port forwards from your own terminal; see SSH from your own terminal.For a coding agent, such as Claude Code or Codex:
Choose File → New VM…, or press New VM… in the Virtual Machines window.
The very first VM downloads the Debian base image (about 3 GB) once. Later VMs are cloned from it and boot in seconds. A VM's disk takes only the room its contents need on the host: 20 GB is how far it may grow, not space set aside.
The System pop-up picks the VM's Linux.
apt, sudo, bash and systemd.apk, not systemd and apt. Its user's shell is ash and it has doas in place of sudo. Prebuilt glibc binaries do not run on its musl libc.An Alpine VM can be made on a Linux host only: on macOS and on Windows exe refuses that system.
exe records which system each VM was made with. Chat, a chat pinned to the VM and the Agent tab are told it, so on Alpine they reach for apk and doas. Publish to GitHub… installs git with apt and expects a Debian VM.
Windows → Virtual Machines lists every VM with its state, its specs and, while it runs, its IP address. Click a column's heading to sort by it, and again to turn the order round. Each VM also has an icon on the desktop.
Right-click a VM for its menu:
| Menu item | What it does |
|---|---|
| Open | Opens the VM's window. |
| Open Terminal | Opens the VM's window on its Terminal tab. |
| btop | Opens the VM's process monitor in an 80×24 terminal window. It runs the VM's installed btop over SSH; press q to quit and close the window. A failed launch leaves its error visible. Only for a running VM. |
| Chat with this VM | Opens the Chat window on this VM, once a chat backend is set up. |
| Stop or Start | The same as the row's button. |
| Restart | Stops a running VM and starts it again. |
| Copy IP | Puts the VM's IP address on the clipboard. |
| Expose Port… | Opens the VM's window on its Expose tab. |
| Publish to GitHub… | Sends a folder of a running VM to GitHub; see Publishing to GitHub. |
| Delete | The same as the row's button. |
Double-click a VM to open its window. The line at its top shows the VM's state, then its IP, how much disk the VM really holds on the host (allocated space, not the sparse file's nominal size) and the guest's system with its version, read from the guest itself. At the right edge is the load average over one, five and fifteen minutes, refreshed every five seconds while the window is open.
| Tab | What it is for |
|---|---|
| Services | The TCP ports listening inside the VM, each with a link that opens it, and the routes already published to the web. A server must bind 0.0.0.0, not 127.0.0.1, to show up here or to be exposed. |
| Terminal | A full SSH terminal in the browser. |
| Agent | Tell the built-in coding agent what to build. It gets a shell in this VM and streams its work live. |
| Expose | Publishes a VM port at an HTTPS subdomain; see Publishing to the web. |
| Sessions | Every chat pinned to this VM, agent runs included, each with a one-line summary a model wrote of what it accomplished. Click one to reopen it in the Chat window. |
| Notes | Free-form notes about the VM, saved automatically. Agents are told to read them before working in an unfamiliar VM, so write down what runs where. Under them the tab shows what the built-in agent has remembered about the VM, with Forget, pressed twice, to erase it. |
Everything the windows do has a command. exe is typed on the machine that runs the daemon. The HTTP calls go to the address the desktop is served at, and are what an agent uses.
| To | Command | HTTP |
|---|---|---|
| List the VMs | exe ls | GET /v1/vms |
| Make a VM and boot it | exe create demo | POST /v1/vms |
| Start a stopped VM | exe start demo | POST /v1/vms/demo/start |
| Stop it, keeping its disk | exe stop demo | POST /v1/vms/demo/stop |
| Delete it and its disk | exe rm demo | DELETE /v1/vms/demo |
| Read its state and IP | exe ip demo prints the IP | GET /v1/vms/demo |
| Read or replace its notes | none | GET or PUT /v1/vms/demo/notes |
| Open a shell or run one command in it | exe ssh demo or exe ssh demo uname -a | none: use SSH |
exe create takes -cpus, -mem (MB), -disk (GB) and -image alpine. Over HTTP the body is JSON, and only name is required: {"name":"demo","cpus":2,"memory_mb":2048,"disk_gb":20,"image":"alpine"}.api_token is set, every HTTP call carries Authorization: Bearer <token>; see Configuration.{"error":"…"}: 404 for a VM that does not exist, 409 for one that is not running, 503 on a machine that cannot run VMs.ssh -p 2222 demo@this-host 'uname -a'. See SSH from your own terminal.Help → Agent Skill Guide… is all of this written for an agent, served at /skill.md. How VMs Work, on the website, says what a VM is made of on Linux, macOS and Windows.
On Linux, where systemd runs exe, the VMs keep running when the daemon restarts: after an update, after Restart in the desktop and after systemctl --user restart exe. The next daemon takes each running VM over as it is. What runs inside does not notice, and a site published from a VM answers again as soon as the daemon is back.
exe stop demo or its window, as before.systemctl --user stop exe leaves the VMs running as well. Stop them first with exe stop when they should not run on without the daemon.KillMode=process. journalctl --user -u exe says which.On macOS and on Windows, and when you start exe serve by hand, the VMs run inside the daemon. When it stops or restarts, they shut down with it, and the ones that were running start again when it comes back.
A node without a hypervisor (a NAS, a container without /dev/kvm) runs the desktop without VMs. The Virtual Machines window stays empty and says why: This node cannot run VMs, followed by the reason. Apple menu → About This Computer gives its VM memory as unavailable on this node. Everything else works as usual. Running without VMs, on the website, has more.