Machinen

Boot Once,
Run Everywhere.

A MicroVM that runs on hardware you already own.
Close your laptop and it hands off to another host.
Works across macOS, Linux, and Raspberry Pi.

# Start here
=== PAUSE HERE. RESUME THERE. ============================================================================

Start work on your laptop. If you need to leave, snapshot the VM and restore it on another machine. The work continues from the same point — same process, same memory, same open files — without starting over.

[LAPTOP]
vm screen
[CLOUD]
VM
tests
tests running
# laptop
1/3 passed...
# cloud
waiting
=== USE IT FROM TYPESCRIPT OR THE SHELL. ============================================================================

The workflow is the same either way: bake an image, boot the VM, run commands inside it, snapshot it, and restore it on another machine. Use the TypeScript API when you're building automation, or the CLI when you're working from a terminal.

> handoff.ts
01import { provision, boot, restore } from "@machinen/runtime";0203const counter = [04  'import { createServer } from "node:http";',05  'let count = 0;',06  'createServer((_, res) => {',07  '  res.end(JSON.stringify({ count: ++count }) + "\n");',08  '}).listen(3000);',09].join("10");1112// 1. Bake the VM with a tiny Node.js HTTP server.13await provision({14  install: async (vm) => {15    await vm.exec("apt-get update && apt-get install -y nodejs");16    await vm.writeFile("/opt/counter.mjs", counter);17  },18  cmd: ["/usr/bin/node", "/opt/counter.mjs"],19  out: "./counter.tar.gz",20});2122// 2. Boot it on your laptop and forward port 3000.23const vm = await boot({24  image: "./counter.tar.gz",25  name: "counter",26  portForward: [{ hostPort: 3000, guestPort: 3000 }],27});2829// 3. Let the process build up state in memory.30await fetch("http://localhost:3000"); // { count: 1 }31await fetch("http://localhost:3000"); // { count: 2 }3233// 4. Battery's dying. Snapshot the whole VM to disk.34await vm.snapshot("./counter.vmstate");3536// 5. On your desktop: restore. Same heap, same counter.37const resumed = await restore("./counter.vmstate");
> terminal.sh
01# 1. Bake the VM.02$ node bake.ts03# → ./counter.tar.gz0405# 2. Boot the counter on your laptop.06$ machinen boot ./counter.tar.gz --name counter --detached -p 3000:30000708# 3. Let the process build up state in memory.09$ curl localhost:300010# → { "count": 1 }11$ curl localhost:300012# → { "count": 2 }1314# 4. Battery's dying. Snapshot the VM state.15$ machinen snapshot counter ./counter.vmstate1617# 5. On your desktop: restore.18$ ssh desktop machinen restore ./counter.vmstate -p 3000:300019$ curl desktop:300020# → { "count": 3 }
=== FREEZE, MOVE, OR COPY A RUNNING VM. ============================================================================

Machinen keeps a running VM intact, which makes three operations possible.

> 01: SNAPSHOT

Save a point in time: the agent conversation, filesystem, memory, open files, timers, and running processes. Experiment like crazy, then come back to a place you remember.

> 02: RESTORE

Want to share your work? Ship an entire machine and let someone else poke and prod a real working system instead of rebuilding it from notes.

> 03: FORK

Make a copy of the running VM and let both continue. Spin up several agents from the same warm state, let them try different approaches, and keep the result that works.

> fork.ts
01const child = await vm.fork({ name: "agent-b" });02// agent-b starts from the same running state, then goes its own way.0304$ machinen fork agent --new-name agent-b --detach
=== DEEP DIVES ============================================================================
> LOCAL-FIRST, BUT TRANSPORTABLE.

Machinen is a VM sandbox for hardware you control, not a cloud runtime. Your source, credentials, and filesystem stay inside a trust boundary you choose. When you do move work, it is an explicit snapshot: restore the same machine state on another host without handing the whole workflow to a remote sandbox.

> A REAL LINUX VM, DEFINED IN TYPESCRIPT.

Machinen runs microVMs, not containers. Snapshot and restore happen at the VM boundary, so the guest moves as one unit: kernel, processes, memory, files, and timers. Build the image in TypeScript: install packages, write files, choose the command. No Dockerfile.

> MOUNT FILES AND FORWARD PORTS.

Mount a host directory into the VM under /mnt/, and the guest sees your edits as you make them. Forward guest ports to your host with one option. No networking setup, no NAT rules.

> RUNS ON MACS AND ARM64 LINUX.

Machinen runs on Apple Silicon Macs, arm64 Linux machines, Raspberry Pi, and Graviton .metal instances. On Linux it uses/dev/kvm; on macOS it uses Hypervisor.framework.

-- COMPATIBILITY --
[x] Apple Silicon Macs
[x] arm64 Linux machines
[x] Raspberry Pi
[x] Graviton .metal
* /dev/kvm on Linux, Hypervisor.framework on macOS