- JavaScript 85%
- C# 7%
- Swift 6.2%
- Shell 1.3%
- PowerShell 0.5%
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. |
||
|---|---|---|
| installer | ||
| mod | ||
| test | ||
| .gitignore | ||
| INSTALL.md | ||
| KEY-MANAGEMENT.md | ||
| LICENSE | ||
| README.md | ||
| SECURITY.md | ||
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.