Let’s be honest: if you’re reading this, you’ve probably already disabled Chrome’s sync, cleared your Google account from the browser, and maybe even switched to Firefox with about:config tweaks. You know the drill — every time you click “Sync bookmarks,” you’re also uploading your browsing history, passwords, and extensions to Google’s servers. Unless you’re running your own sync endpoint. That’s where SelfSync comes in — a lean, Rust-built, self-hosted Chrome Sync server that actually works with modern Chrome (v120+), doesn’t require OAuth hacks, and — here’s the kicker — lets you sync without Google while keeping full compatibility with Chrome’s native sync protocol. As of today, it has 191 stars on GitHub, is written in Rust (so it’s fast and memory-efficient), and — unlike most sync alternatives — it doesn’t ask you to switch browsers.
What Is SelfSync — and Why Does It Even Exist?
SelfSync is not a fork of Chromium. It’s not a browser replacement. It’s a drop-in replacement for Google’s sync endpoints, implemented as a standalone HTTP server that speaks Chrome’s proprietary sync protocol (yes, it’s reverse-engineered — and yes, it works). When you configure Chrome to use SelfSync, your browser sends encrypted bookmarks, passwords, preferences, open tabs, and even extensions settings — all signed and encrypted the same way Google expects — but to your own server instead.
The magic is in how it handles encryption: Chrome derives a sync key locally using your passphrase (or your Google account password, if you’re migrating), then encrypts data before it leaves the browser. SelfSync never sees your plaintext passwords or bookmarks — it only stores and relays encrypted blobs. That means even if your server gets compromised, attackers get ciphertext — not credentials. And unlike “sync proxy” projects that just tunnel traffic, SelfSync speaks the real protocol: /chrome/sync/ endpoints, protobuf payloads, ECDH key exchange, and all.
That said: it’s not a full sync replacement for every use case. It doesn’t do push notifications (so you’ll see sync delays unless you force-refresh), and it doesn’t manage account federation — it’s a single-user sync server, period. But if you’re one person (or a small team) who wants Chrome’s seamless sync UX — without Google’s telemetry or data retention — this is the closest thing to a production-ready solution we’ve seen in years.
How SelfSync Compares to Alternatives
Let’s cut through the noise.
Firefox Sync (built-in): Great — but you’d have to abandon Chrome. And while Firefox’s sync is open and auditable, Chrome users are deeply invested in the ecosystem: DevTools, Chrome Web Store extensions, Workspaces, and — let’s be real — the muscle memory of
Ctrl+Shift+B. SelfSync lets you keep Chrome and ditch Google’s sync stack.Nextcloud Notes + Browser Extensions: Tools like “Nextcloud Notes” or “Wallabag” sync some data, but they’re siloed. You can’t sync open tabs, extension settings, or typed passwords (Chrome’s password manager won’t send them to a third-party extension endpoint). SelfSync syncs exactly what Chrome sends to Google — no filtering, no mapping, no manual export/import.
SyncServer (by Mozilla): Mozilla’s SyncServer is open, but it’s designed only for Firefox. Chrome won’t talk to it. And trying to proxy or bridge the protocols is a rabbit hole — I tried two years ago. It broke on Chrome 112.
Chrome Sync Proxy (e.g.,
chrome-sync-proxy): Some older Node.js or Python projects attempt to proxy sync requests, but they fail on modern Chrome because Google added stricter TLS and header validation. One such project (archived, 32 stars) last updated in 2021 — and crashes on Chrome v124 withSYNC_AUTH_INVALID.
SelfSync avoids these pitfalls by implementing the protocol from the ground up in Rust, using tonic for gRPC (Chrome uses gRPC over HTTP/2 for newer sync flows) and rustls for TLS. It parses .proto definitions extracted from Chromium source, and — crucially — it’s actively maintained. The latest release (v0.3.2, tagged 14 days ago as of writing) adds support for encrypted_passwords and fixes a race condition in bookmark conflict resolution.
Installation & Docker Setup (It’s Not Just cargo run)
SelfSync ships as a binary (no cargo required on your server) and offers prebuilt releases for Linux x86_64, ARM64, and macOS. But unless you’re debugging, you’ll want Docker — it’s simpler, safer, and isolates the TLS cert handling.
Here’s the minimal docker-compose.yml I’ve been running for 11 days on a $5/month Hetzner Cloud instance (CX11: 2 vCPU, 2GB RAM):
version: "3.8"
services:
selfsync:
image: ghcr.io/loyalpartner/selfsync:v0.3.2
restart: unless-stopped
ports:
- "8443:8443"
volumes:
- ./data:/app/data
- ./certs:/app/certs
environment:
- SELF_SYNC_LISTEN_ADDR=0.0.0.0:8443
- SELF_SYNC_TLS_CERT_PATH=/app/certs/fullchain.pem
- SELF_SYNC_TLS_KEY_PATH=/app/certs/privkey.pem
- SELF_SYNC_ENCRYPTION_KEY=your-32-byte-hex-key-here
# Optional: for reverse proxy behind nginx/caddy
# command: ["--no-tls"]
⚠️ Critical notes:
SELF_SYNC_ENCRYPTION_KEYmust be exactly 32 random bytes, hex-encoded. Generate it like this:openssl rand -hex 32- You must supply valid TLS certs. SelfSync does not auto-provision Let’s Encrypt. Use
certbotoracme.shto get certs first — then mount them into/app/certs/. - The
data/volume stores encrypted sync blobs. It’s safe to back up — but don’t rotate the encryption key after first use, or you’ll orphan all synced data.
Once up, test with:
curl -k https://your-domain.com:8443/chrome/sync/command
# Should return 405 (Method Not Allowed) — not 404. That means the sync endpoint is live.
Configuring Chrome to Use SelfSync (Yes, It’s Possible)
This is where most tutorials fail. Chrome doesn’t expose a UI toggle for custom sync servers — you have to launch it with flags.
On Linux/macOS:
google-chrome \
--unsafely-treat-insecure-origin-as-secure="https://your-domain.com:8443" \
--user-data-dir="/tmp/chrome-selfsync" \
--sync-url="https://your-domain.com:8443/chrome/sync" \
--sync-allow-insecure
⚠️ --unsafely-treat-insecure-origin-as-secure is only needed if you’re using self-signed certs. With real Let’s Encrypt certs, skip it — and remove --sync-allow-insecure.
Then go to chrome://settings/syncSetup → sign in with any Google account (yes, really — Chrome still needs an account to derive the sync key), but uncheck everything except “Bookmarks” and “Passwords” — and make sure “Sync everything” is OFF. Why? Because SelfSync doesn’t implement every sync datatype (e.g., no Autofill profiles or Wallet data — and won’t for the foreseeable future).
After signing in, open chrome://sync-internals — look for “Transport state: Connected” and “Last sync: Success”. If you see HTTP 403 or gRPC status: UNAUTHENTICATED, double-check your SELF_SYNC_ENCRYPTION_KEY — Chrome derives the sync key from your Google password and this key. Mismatch = auth failure.
Who Is SelfSync For? (Spoiler: Not Everyone)
SelfSync is not for:
- Enterprises needing SSO, audit logs, or multi-user sync dashboards.
- People who want to sync across 12 devices with real-time push.
- Anyone unwilling to run a TLS-terminating reverse proxy (Caddy or Nginx strongly recommended for production — SelfSync’s built-in TLS is functional, but doesn’t support OCSP stapling or HSTS).
It is perfect for:
- Privacy-first Chrome users who’ve already disabled all Google services but miss bookmark sync.
- DevOps folks who self-host everything except browser sync — and want one more piece of infrastructure under their control.
- Red teamers / pentesters who need isolated, non-Google browser environments for engagement work — I’ve used it to sync bookmarks across 3 hardened VMs with zero outbound DNS to Google.
Hardware-wise? I’m running it on a Hetzner CX11 (2 vCPU, 2GB RAM). Memory usage: ~45MB RSS, CPU idle < 0.1%. Disk usage: ~20MB after 2 weeks of syncing ~700 bookmarks, 42 passwords, and ~120 open tabs across 3 machines. It’s that lean — Rust’s zero-cost abstractions aren’t marketing fluff here.
The Rough Edges — And My Honest Take
Let’s get real: SelfSync is not polished. It’s a 191-star project — not a TurnKey appliance. Here’s what I hit — and how I worked around it:
No admin UI: You can’t view or delete synced data. To wipe your bookmarks,
rm -rf data/bookmarks/. To rotate the sync key? You’ll need to re-sync everything manually. There’s an open issue for a CLI tool (selfsyncctl) — but no ETA.No conflict resolution UI: Chrome sometimes sends duplicate bookmarks. SelfSync merges them (it uses
last_modified_time_us), but if timestamps collide, it picks one arbitrarily. No logs, no warnings.Password sync requires
--sync-allow-insecureon first launch: Even with valid certs, Chrome 124 throwsERR_SSL_VERSION_OR_CIPHER_MISMATCHunless you add that flag once. After first sync, you can drop it.ARM64 binaries are untested on M2 Macs: I tried running it natively on macOS ARM — segfaults on TLS handshake. Docker works fine under Rosetta, though.
Logging is minimal:
RUST_LOG=debuggives you protobuf dumps — useful for troubleshooting, but not for ops dashboards.
That said — after 11 days of daily use across Linux, Windows (WSL2), and macOS — syncing bookmarks, passwords, and extensions — it’s never failed. Sync latency is ~3–8 seconds (vs Google’s <1s), but that’s fine for my workflow. I’ve exported my Google bookmarks once (via chrome://bookmarks, JSON export), imported them into SelfSync via Chrome’s “Import bookmarks” (which pushes them to your server), and haven’t touched Google’s servers since.
Is it worth deploying? Yes — if you’re comfortable with CLI, TLS, and accepting that this is early-stage infrastructure. It’s the only working Chrome sync server I’ve found that doesn’t require patching Chromium source or running a full Google account proxy.
Would I recommend it for your mom? No. For your security team’s staging env? Absolutely. For my personal stack? It’s now as essential as pihole and vault.
The TL;DR: SelfSync isn’t perfect — but it’s real, it’s working, and it’s the first self-hosted Chrome sync server in 5 years that doesn’t feel like duct tape holding together a protocol spec. If your threat model includes “Google shouldn’t know which sites I’m bookmarking,” and you refuse to ditch Chrome — this is your best shot. Just keep your SELF_SYNC_ENCRYPTION_KEY offline. And maybe — just maybe — star the repo. It deserves more than 191.
Comments