Tomo

Ridiculously fast bidirectional code sync

Save a file on your laptop and KAPOW! it instantly syncs to your Linux box.

Your Linux box generates a new asset and SWOOSH! it syncs back to your laptop.

Every save is kept. Roll back to any version at any time.

Zero server-side setup

$ curl -fsSL https://tomo-sync.dev/install.sh | sh

or build from source · github.com/jakequist/tomo

Rust MIT single static binary Linux + macOS no root · no daemon
A developer at a cozy floating-island desk with a laptop, a sleeping cat and flowers, joined by a glowing stream to a floating GPU tower running Linux

Tomo was born out of the GPU workflow.
Edit files on your mac and sync them to your GPU workstation.
Non-GPU workflows are also welcome!

dev@laptop — ~/proj

the interface

Watch it work — from any terminal

Run tomo sync on a terminal and you get a live view of the session: the calm stream you already know, plus a heartbeat that proves it's alive and a conflict center one keypress away. Detach and it keeps syncing; re-attach from anywhere.

tomo sync — dev@laptop
connected vm8 (192.168.1.40) src/train.py 1.2 kB src/config.yaml 842 B conflict src/train.py — kept vm8's copy · c to review assets/logo.png 14 kB model.ckpt ██████████░░░░░░ 58% vm8 (192.168.1.40) ✓ connected · ⚠ 1 · last sync 2s ago · c conflicts · d detach · ? help

The body is the stream — same glyphs, same words as the plain output. The TUI adds only the pinned transfer zone and the status line: peer, connection, a badge, and a last sync heartbeat so a silent screen still reads as alive.

tomo sync — conflict center
tomo ── vm8 ── connected ── ⚠ 3
CONFLICTS
> src/train.py 2m ago kept: vm8's copy src/config.yaml 2m ago kept: vm8's copy adoption from vm8 (12 files) ▸
src/train.py on disk now — vm8, 2s ago in history — you, 5s ago ────────────────────────── @@ -18,7 +18,9 @@ - lr = 3e-4 + lr = 1e-4 + warmup = 500
enter keep · t take yours · b keep both · space skip · a ack all · u undo · ? help = tomo conflicts resolve 7 --keep-current

A conflict never blocks — the tree already converged and the loser is safe in history — so this is a review, not a merge prompt. Framed as on disk now vs in history, one keypress per verdict, and u undoes any of them. The bottom line always shows the exact CLI command, so the TUI teaches its own scriptable twin.

What you get

Six things it gets right.

// instant

~6ms, both ways

Save a file and it's on the box in a few milliseconds. It stays that fast whether the tree has ten files or ten thousand, because Tomo watches for changes instead of scanning. The build's output comes back just as quick.

// undo

Every save is an undo point

Every save is versioned on disk. tomo log shows the versions, tomo diff compares two of them, tomo restore brings one back. It's undo that survives closing your editor.

// safe

Conflicts never lose work

Edit the same file on both machines at once and neither side blocks. They independently land on the same winner, and the version that lost gets saved to history where you can pull it back. No merge prompts, no lost edits.

// zero-setup

Nothing to install on the server

Tomo copies itself to the server over the SSH connection you already use and runs from there. You don't need root, a package manager, a daemon, or an open port.

// resilient

Survives things going wrong

kill -9 it mid-write and nothing's half-written. Fill the disk and it stalls loudly instead of dying. Drop the network and it reconnects and catches up. A server clock years out of sync doesn't matter, because ordering uses vector clocks, not wall time.

// portable

One static binary

One file, no dependencies, Linux and macOS. Drop it on your PATH and run it. That same binary is what gets pushed to the server, so both ends always match.

Speed, measured

~60× fasterper sync, on a 20,000-file tree over SSH
tomo  save→arrival 6 ms rsync  one sync, any size ~370 ms 0 100ms 200ms 300ms 400ms milliseconds

tomo is event-driven, so save-to-arrival is ~6 ms whether the tree has 10 files or 20,000. rsync rescans the whole tree every run (~370 ms here), and that cost grows with the tree, cold caches, and network hops. Bulk seeding is still rsync's job today — seed the box however you like, tomo reconciles whatever's already there. Full methodology and raw numbers →

How you use it

Three commands. That's the whole loop.

01

sync

Point it at the box once. First run, it makes the current folder a Tomo project automatically (everything goes in .tomo/), installs itself there, and starts syncing both ways — with a live view in your terminal (press c for conflicts).

$ tomo sync you@gpu-box:~/proj
02

conflicts

Both machines touch one file at once? A deterministic winner lands and the loser is kept in history — sync never blocks. Review them whenever you like.

$ tomo conflicts
03

restore

Roll a file back to an earlier save. If a session's running, the restored version syncs over too.

$ tomo restore src/main.rs

Check out the docs →

Shamelessly AI Native. This project was built with Claude Code (Fable & Opus). In many aspects, the quality is much higher than I could have done on my own (especially within a reasonable time frame).
If you want to customize this project, I encourage you to fork it and use your own coding agent. I try to keep the repo AI-friendly, so your coding agent should "just work".
What makes the repo agent-friendly →
Get started →