A script module for the Zen browser to enable sync between browsers on different machines, owned by the same user. Uses a private git repository for back-end sync, with options for periodic automation and auto-merge logic. Changes appear immediately in-browser.
  • JavaScript 85%
  • C# 7%
  • Swift 6.2%
  • Shell 1.3%
  • PowerShell 0.5%
Find a file
Elliot 7b5884ac9e v4.0.2 mod source + docs — pin convergence, panel truth, faster sync
Pins with no stored title were written two ways and never compared equal, so
machines sat reporting "diverged" with nothing wrong; both spellings now
normalize to one. The divergence panel reports a true total instead of a capped
list. Apply operations report failures they cannot complete rather than
returning success, and folder un-nesting works (it was a silent no-op). A sync
that changes something takes ~1.7s instead of ~66s: the time was a redundant
fetch inside the push path.

Hardening from the release review: keyring written atomically, peer-controlled
ids redacted from logs, a corrupt packfile no longer reads as an empty trunk, a
state-read fault no longer silently resets the anti-rollback high-water, and an
async boot failure is logged instead of leaving sync silently unarmed.

extract-5 / sync-8 / apply-host-13 / transport-4 / schema-5 / crypto-2 /
keystore-2 / apply-2, new log-hygiene-1. Payload: signed v24.

Docs updated for the key rotation: 4.0.2 is signed with new keys and the
out-of-band fingerprint has been replaced, so older deployers refuse the new
payload and previously published artifacts no longer verify. INSTALL explains
what the deployer says when it rejects a payload and why.
2026-09-01 12:09:26 -04:00
installer v4.0.2 mod source + docs — pin convergence, panel truth, faster sync 2026-09-01 12:09:26 -04:00
mod v4.0.2 mod source + docs — pin convergence, panel truth, faster sync 2026-09-01 12:09:26 -04:00
test v4.0.2 mod source + docs — pin convergence, panel truth, faster sync 2026-09-01 12:09:26 -04:00
.gitignore zen-sync 4.0 — initial public release 2026-06-29 13:45:52 -04:00
INSTALL.md v4.0.2 mod source + docs — pin convergence, panel truth, faster sync 2026-09-01 12:09:26 -04:00
KEY-MANAGEMENT.md v4.0.2 mod source + docs — pin convergence, panel truth, faster sync 2026-09-01 12:09:26 -04:00
LICENSE zen-sync 4.0 — initial public release 2026-06-29 13:45:52 -04:00
README.md v4.0.2 mod source + docs — pin convergence, panel truth, faster sync 2026-09-01 12:09:26 -04:00
SECURITY.md v4.0.2 mod source + docs — pin convergence, panel truth, faster sync 2026-09-01 12:09:26 -04:00

zen-sync

Keep your Zen Browser setup the same on all your computers.

If you spend time arranging workspaces, sidebar folders, pinned sites and containers, you probably want that arrangement on your laptop too. zen-sync copies it between machines you own: workspaces, sidebar folders, pinned sites, essentials, containers, and Zen mod themes.

It does not sync your browsing. Loose tabs, history, scroll position and cookies stay on the machine they belong to. What travels is the structure you set up, not what you happen to be doing right now.

There is no account and no service in the middle. Your machines talk to each other through a git repository you control -- a private repo on GitHub or GitLab, a Forgejo box in your basement, whatever you already have. Snapshots are encrypted on your machine before they are pushed, so whoever hosts the repo stores ciphertext and nothing else.

NOTE: This project was highly vibe-coded with Claude Opus 5; I'm a security guy, not a software developer. Drop me a line if you see anything wrong or improvements I should make.

Getting started

INSTALL.md walks through it: download a signed deployer, verify it, run it, then finish setup inside Zen. You do not need Node.js, keys, or a build toolchain to install.

Setup asks for two things: the git repo to sync through, and an encryption key. The key is generated on your first machine and typed into the others. Keep a copy somewhere safe -- KEY-MANAGEMENT.md explains why, and what the second key system (payload signing) is for.

If you want to build it yourself instead, see the bottom of INSTALL.md.

How it works

There are two pieces.

The mod (mod/) runs inside Zen as privileged JavaScript. It reads and writes your profile structure through Zen's live session model, so nothing has to be edited on disk and you never have to quit the browser for a change to land. It also handles the encryption and the git push and pull.

The deployer (installer/) is the installer. Its job is narrow: check that the payload it was given is genuinely signed, refuse it if not, ask you separately about disabling the script sandbox, then write the mod into your profile. There is a reference CLI plus native GUI deployers for Windows, macOS and Linux.

Syncing itself is a three-way merge, the same shape git uses. Each machine reads its current Zen structure, compares it against what the shared repo last looked like and what it looks like now, works out the combined result, applies that back into the running browser, and pushes. Items carry stable ids that survive across machines, so a folder renamed on one machine is recognised as the same folder on the other rather than showing up as a new one. Each snapshot is sealed with XChaCha20-Poly1305 under a key you hold and distribute yourself.

Repository layout

mod/            the in-Zen privileged-JS mod
  src/          crypto, transport, extract, merge, apply, sync, ui/, state
  loader/       the AutoConfig bootstrap (config.js + config-prefs.js)
  vendor/       pinned, vendored deps (@noble/*, isomorphic-git) -- no bundler at runtime
installer/      the deployer (verify a signed payload, then lay it into Zen)
  src/          the trust core + CLI: verify, install, sign, zsi, provenance, cli
  windows/      .NET 8 WinForms native deployer (source)
  macos/        Swift native deployer (source)
  linux/        Node single-binary / script deployer (source)
test/           the mod's smoke suite (pure node, no deps): smoke.mjs + suites/ + fakes
README.md       this file
INSTALL.md      build + install + first-run setup
KEY-MANAGEMENT.md   the two key systems (content encryption + payload signing)
SECURITY.md     threat model, reporting
LICENSE         MIT

Status

Current release: 4.0.2. This is a bugfix release on the 4.0 line. No new synced fields and nothing new in the interface, so a 4.0.1 machine and a 4.0.2 machine sync with each other happily.

What changed:

  • Pins converge. A pin with no stored title could be recorded two different ways on two machines, and the two spellings never matched, so a pair of machines could sit there reporting "diverged" with nothing actually wrong. Force-pull was the only way out. Both spellings are now written the same way.
  • The panel reports the real number. The divergence list only ever showed four items and gave no total, so fixing one made another appear and you could never tell how many there were.
  • Apply operations report what they cannot do instead of returning success. Folder un-nesting used to do nothing at all, silently; it works now.
  • A sync that changes something takes about 1.7 seconds instead of about 66. The time was going into a redundant network round trip in the push path.

If you already have zen-sync installed: 4.0.2 is signed with new keys, and the fingerprint published over DNS has been replaced. Read the note at the top of section 2 in INSTALL.md before you verify a download.

4.0 was a ground-up redesign. The 1.x-3.x releases were a Python tool over a shared cloud folder and are not in this repository.

License

MIT