Every machine, always current
Your jj work, on every machine, all at once.
Work on your laptop, close the lid, and sit down at your desktop: the change you were working on is already there. Coding agents on three machines see each other's work as it happens. No pushing work in progress, no fetching it back, no wondering which machine is behind.
For jj, the git-compatible version control system. All it needs is ssh to one machine that's usually on.

Watch it happen
Describe a change on the laptop. Before you could reach the desktop’s keyboard, it’s in
jj log there, with no push and no fetch. In the middle, musubi top on the hub shows it
going through.
laptop
laptop ~/src/app ❯ jj describe -m "Retry failed fetches"
Working copy (@) now at: zvrozmvy 76deb1ed (empty) Retry failed fetches
Parent commit (@-) : lpolomsm d91c0a5a main | Add a fetcher
laptop ~/src/app ❯ echo 'RETRIES = 3' >> fetcher.py
laptop ~/src/app ❯ jj diff
Modified regular file fetcher.py:
...
3 3:
4 4: def fetch(url):
5 5: return urllib.request.urlopen(url).read()
6: RETRIES = 3
laptop ~/src/app ❯ jj log
○ tmzzmlto you 2026-10-27 15:29:11 desktop/default@ 32ec8de7
│ (empty) (no description set)
@ zvrozmvy you 2026-10-27 15:29:06 default@ 51a8f8be
│ Retry failed fetches
◆ lpolomsm you 2026-10-27 15:28:47 main d91c0a5a
│ Add a fetcher
~
musubi top on the hub
musubi top: 1 hub, every 1s
This machine's daemon is running, serving 0 repositories.
Hub /private/tmp/mjd.f6YvjM/hub/musubi-hub: up 32s, musubi 0.1.0, 1 hive
HIVE HEAD IN/s OUT/s OPS COMMITS MACHINES ISSUES
app #7 0 B/s 0 B/s 8 4 2/2
app since the hub started: received 9.1 KiB and sent 10 KiB; 8
operations, writing 4 commits, came in, and 10 went out; 7 pushes moved
MACHINE HEARD AT MUSUBI STATE
desktop 2s ago #7 0.1.0 up to date
laptop 2s ago #7 0.1.0 up to date
AGO HEAD FROM OPS COMMITS WHAT
8s ago #7 desktop 1 1 new empty commit
13s ago #6 laptop 1 1 snapshot working copy
21s ago #5 laptop 1 1 describe commit 9c4d26
31s ago #4 desktop 1 1 new empty commit
q quit ↑↓ choose a hive r refresh + slower - faster
desktop
@ wqotzwym you 2026-10-27 15:28:48 default@ 729409a5
│ (empty) (no description set)
│ ○ zvrozmvy you 2026-10-27 15:29:06 laptop/default@ 51a8f8be
├─╯ Retry failed fetches
◆ lpolomsm you 2026-10-27 15:28:47 main d91c0a5a
│ Add a fetcher
~
^C
desktop ~/src/app ❯ jj new laptop/default@
Working copy (@) now at: tmzzmlto 32ec8de7 (empty) (no description set)
Parent commit (@-) : zvrozmvy 51a8f8be Retry failed fetches
Added 0 files, modified 1 files, removed 0 files
musubi top on the hub shows
each operation arrive and go out; the desktop's jj log, run again every
half second, shows the laptop's working copy, laptop/default@, change a
moment later. Then the desktop starts a change on top of the laptop's, and the laptop
sees it. Recorded from real jj and musubi.What Meta and Google engineers already have
Engineers at Meta never push work in progress just to move it between machines: Sapling’s Commit Cloud uploads every commit as soon as it’s made. Engineers at Google have something like it in an internal jj server that keeps their repositories’ history in the cloud. jj-musubi brings that to your own repositories, on your own machines, over plain ssh, with no service to sign up for and nothing leaving machines you control.
What you get
Agents everywhere, all at once
Run Claude Code or Codex on your laptop, your desktop and a couple of devboxes, all in
one repository. One jj log, on any machine, shows what every agent everywhere
is working on, as devbox/default@: the devbox's working copy. Review it from
anywhere, or hand it to an agent on another machine with
jj new devbox/default@.
Every machine current
Laptop, desktop, home server: each has every commit, bookmark and change you've made on
any of them, within a second or so of the jj command that made it. A machine
that was asleep catches up within seconds of waking, so you never have to remember which
one is behind.
Close the lid, pick up anywhere
Shut the laptop at work and go home. The desktop already has everything up to your last
jj command, as laptop/default@. Open the laptop again, and it
catches up with the evening's work within seconds of waking. Offline on a plane? It
catches up when you land.
GitHub, everywhere at once
jj git fetch on one machine, and every machine has the new
main@origin. jj git push from the desktop, and the laptop shows
it pushed. Fetch once, not once per machine.
Undo that follows you
jj records every command you run, so that jj undo can take any of them back.
jj-musubi shares that record, so a mistake made on one machine can be put right from any
other.
Your files stay yours
jj-musubi never writes to your working copy. When another machine rewrites the commit
you're on, jj says so, and jj workspace update-stale brings your files up to
date when you're ready.
Start with three commands
Start a hub
On a machine that is usually on, such as a devbox or a home server:
musubi hubShare a repository
In the repository on one machine:
musubi create --hub devboxJoin the other machines
In the same repository on each other machine. On a machine that doesn't have it yet,
musubi clonemakes it.musubi join --hub devbox
That’s all: from then on, keep using jj. You need jj 0.46.0 and git on every machine, and ssh from each to the hub’s machine. Get started covers installing and each step.
A hub, and a daemon on each machine
One machine that is usually on runs a hub, and a daemon on each machine keeps its
repositories in sync with it. Other machines reach the hub over ssh: if ssh devbox works, so
does jj-musubi. The hub decides the order in which machines’ work lands, and holds nothing the
machines don’t have too: a hub that’s lost loses no work.
flowchart LR
subgraph laptop["laptop"]
R1["~/src/app"] --- D1["daemon"]
end
subgraph devbox["devbox"]
H["musubi hub"]
end
subgraph desktop["desktop"]
D2["daemon"] --- R2["~/code/app"]
end
D1 <-->|ssh| H
H <-->|ssh| D2Built to be trusted
A sync that drops a commit, or applies the same rebase twice, is worse than none. So jj-musubi was built proof first.
Proved in Lean
The sync protocol is modelled in the Lean theorem prover, with machine-checked proofs that no work is lost, no merge is done twice, and every machine ends up the same, over a network that loses and reorders messages, with machines and the hub crashing at any point, even when a power cut sets the hub back.
Checked against the proof
In testing, the Rust protocol code runs beside an executable version of the Lean model, which checks every step it takes. Deliberately broken versions of the code get caught.
Every race, with a test
More than 70 races between machines, from the same commit rewritten on two machines to one forgetting another's workspace, each with its outcome pinned by a test on real repositories.
Searched through real jj
Every night, a generated search runs real jj commands on real repositories
through crashes, lost replies and power cuts, and checks the result against what jj
itself would do.
How jj-musubi keeps your work safe tells the whole story.
Why not file syncing, or a git remote?
Syncing a repository with Dropbox or Syncthing shares the working copy too, so machines fight
over one checkout, and jj’s own documentation warns that repository corruption is possible.
Pushing work in progress to a git remote carries only the commits you put a bookmark on, takes
a push on one machine and a fetch on the other every time, and leaves jj undo behind on each
machine. How jj-musubi compares goes through each approach,
and when it suits.