Highly vibecoded! Unstable! Proof of concept! Dont use (yet)!
Cross-platform (Windows/MacOS/Linux) Chromium-based browsers bidirectional profiles sync system to use with cloud folders (I use selfhosted OpenCloud).
It will keep extensions (with their settings!) and some other stuff to be identical across my systems. Google Sync makes a little part of that - also not open-source and not available on Helium/Ungoogled Chromium.
- Thorium
- Helium
- Chrome
- Yandex
The architecture supports adding more Chromium-derived browsers with minimal
changes (one file per browser) onto src\browsers.
| Data | Synced |
|---|---|
| Bookmarks | Yes |
| Extensions | IDs only / unpacked ones sync full code |
| Extension settings/storage/cache | Yes (not 100% sure works for everything) |
| Local Storage | Yes |
| Preferences | Yes — part of unencrypted ones |
| Custom Dictionary | Yes |
| Search Shortcuts | Yes — user-created engines only |
| Themes | Yes — only active one |
| Flags | Yes — changed ones |
User-created search engines (custom shortcuts in the omnibox) are extracted from
the browser's Web Data SQLite database and stored as search_shortcuts.json
in the sync folder root. This file is shared across all browsers syncing to the
same folder.
Built-in engines (Google, Bing, etc.) are INTENTIONALLY always deleted. User has to replace the default one with its own one.
Passwords, cookies, payment data, and browsing history are intentionally excluded. These are protected by OS-level encryption (e.g. macOS Keychain, Windows DPAPI) that ties the data to a specific machine.
Sessions, autofill data/profiles - no need, annoying for my use cases.
Favicons - not worth syncing.
Files automatically excluded from sync (waste space, no value):
._*— macOS metadata files on exFAT/FAT32 drives
Requirements: Python 3.12+, uv, rclone
make installWhat install does:
- Builds the executable/bundle
- Kills any running instance
- Installs to platform-specific location
- Launches the app
- (macOS only) Removes Gatekeeper quarantine
Extracts user-created search engines from Web Data SQLite
(prepopulate_id = 0 only). On Windows, computes mandatory url_hash BLOB
(AES-256-GCM over SHA-256 of a Chromium Pickle); rows without a valid hash are
silently dropped at startup. See
docs/search-shortcuts.md for full implementation
details.
It's impossible to have identically working extensions installing system across all browsers and it also may conflict. For example, Thorium and Chrome use the same registry paths to look for extensions, so if you start managing Thorium, extensions will also install to all used profiles of Chrome.
For Windows extensions installed via registry keys (per-extension prefs key
plus ExtensionInstallForcelist policy key, both under HKCU).
For Linux: force-list policy files written to
/etc/chromium/policies/managed/<browser>-syncer.json via pkexec for
browsers that support it (e.g. Helium); falls back to per-user
External Extensions/<id>.json stubs otherwise. Force-list entries are
bare IDs (no ;<url> suffix) — this is the only reliable path on
ungoogled-chromium / Helium, where the bundled extstore-fixups extension
proxies Web Store fetches when no explicit update URL is given.
For macOS: per-user External Extensions/<id>.json stubs only.
Some files are intentionally excluded being useless and taking a lot of space. For example, uBlock Origin rules compilated file has no need to be synced, it might be generated on browser launch.
Some browsers are marked as ungoogled in their definition (currently: Helium). Ungoogled browsers strip out Google-specific built-in features such as translation, so they need extensions to compensate (e.g. a translation extension like Linguist). Installing those same extensions in a regular browser (Chrome, Thorium) that already provides the feature natively would be redundant.
To mark an extension as ungoogled-only, add its Chrome Web Store extension ID to the
ungoogled_only_extensions list in the app config
(%APPDATA%\chromium-profile-syncer\config.json on Windows,
~/.config/chromium-profile-syncer/config.json elsewhere):
{
"ungoogled_only_extensions": [
"gbefmodhlophhakmoecijeppjblibmie"
]
}During restore and extension registration, these IDs are silently skipped for non-ungoogled browsers. The backup archive always contains the extension settings (they are sourced from whichever ungoogled browser is being synced), so the data is preserved — it just is not applied to browsers that don't need it.
#middle-click-autoscroll
#force-dark-mode
#enable-force-dark
#set-ipv6-probe-false
#disable-search-engine-collection
#force-punycode-hostnames
#scroll-tabs
#popups-to-tabs
#disable-link-drag - well, check whats this owo
#hide-fullscreen-exit-ui
#disable-top-sites
- search shortcut gru by default - is that possible to do automatically?