A robust, zero-dependency Python script that performs a direct, one-way native synchronisation of Google Chrome bookmarks to Apple Safari on macOS.
This tool bypasses third-party cloud services by parsing Chrome's local JSON bookmark database and surgically injecting it into Safari's binary Bookmarks.plist. It is designed for users who want to use Chrome as their primary browser on macOS but maintain a perfectly mirrored, native bookmark experience in Safari (and by extension, iOS Safari via iCloud).
- Interactive Profile Selection: If you use multiple Chrome profiles, the script dynamically reads Chrome's
Local Statefile. It presents a clean terminal menu displaying your actual profile names, allowing you to choose exactly which profile to synchronise. - iCloud Metadata Preservation (Surgical Injection): Instead of generating a completely new file that iCloud might reject (which causes bookmarks to disappear after a few seconds), the script surgically injects Chrome's bookmarks into Apple's existing root folders. This preserves iCloud's hidden sync keys and
WebBookmarkIdentifierflags, ensuring your Start Page Favorites stay exactly where they belong. - Smart UUID Mapping (Anti-iCloud Churn): Safari requires a unique UUID for every bookmark. A blind overwrite generates new UUIDs, which causes iCloud to see a massive "delete all/re-add all" event β often resulting in duplicated folders on iOS. This script first reads your existing Safari database, maps the UUIDs of known URLs and folders, and reuses them. To iCloud, the sync simply looks like a minor delta update.
- Automated Cache Management: macOS aggressively caches browser preferences. The script uses Python's
subprocessto safely halt Safari, release the database locks, write the new file, and kill thecfprefsddaemon to clear the memory cache automatically. - Automatic Backups: Before modifying anything, the script creates a timestamped backup of your existing Safari bookmarks in
~/Library/Safari/Bookmarks_Backup/. - Zero Dependencies: Built entirely with standard Python 3 libraries (
json,plistlib,subprocess,uuid). Nopip installrequired.
Because modern macOS heavily sandboxes and protects browser data, your terminal emulator must have Full Disk Access to modify Safari's preference files. If you skip this step, the script will abort with a "Permission Denied" error.
- Open System Settings -> Privacy & Security -> Full Disk Access.
- Toggle the switch to On for the terminal application you are using (e.g., Terminal, iTerm2).
- Clone or download this repository to your Mac.
- Crucial: Ensure you have opened Safari at least once so it generates its default bookmark structure and iCloud metadata. If the
Bookmarks.plistfile is completely missing, the script will prompt you to open Safari first. - Open your terminal and run the script:
python3 chrome_to_safari.py- The script will safely close Safari if it is running.
- You will be prompted to select which Chrome profile you want to use as the source.
- The script will back up your current Safari bookmarks, map existing UUIDs, and perform the synchronisation.
- Once complete, simply open Safari. Your Chrome bookmarks will be natively populated.
The script reads Chrome's bookmark JSON located at ~/Library/Application Support/Google/Chrome/[Profile]/Bookmarks.
It recursively maps Chrome's url and folder nodes to Safari's strictly required WebBookmarkTypeLeaf and WebBookmarkTypeList dictionary structures. Instead of overwriting the entire file, it targets the Children arrays of Safari's existing BookmarksBar and BookmarksMenu root folders. It then dumps this modified structure using plistlib.FMT_BINARY, as Safari is notoriously finicky and will reject standard XML plists.
- One-Way Sync: This is a destructive overwrite from Chrome β to β Safari. Chrome acts as the absolute master list. If you manually create a bookmark in Safari, it will be wiped out the next time you run this script.
- Use at your own risk: While the script automatically backs up your previous plist, modifying macOS browser databases directly carries inherent risks.