A complete Python-based migration tool that converts Arc browser spaces, pinned tabs, and open tabs into Zen browser workspaces with proper tab assignment.
- Python 3.7+
- Arc Browser (with spaces and pinned tabs you want to migrate)
- Zen Browser (installed and run at least once)
- macOS or Windows (current implementation)
- lz4 Python package (for session tab injection):
pip install lz4
- Clone this repository:
git clone https://github.com/rafcabezas/arc2zen.git
cd arc2zen- Install the optional dependency for session tab injection:
pip install lz4Run the complete migration (recommended for first-time users):
# Dry run first to see what will be migrated
python3 migrate_arc_to_zen.py --dry-run
# If everything looks good, run the actual migration
python3 migrate_arc_to_zen.py
# Then inject all tabs into the session file (makes tabs actually appear)
python3 inject_session_tabs.py
# Finally, inject Arc's open (unpinned) tabs (Zen 1.20+ keeps TWO session files)
python3 inject_open_tabs.py --dry-run
python3 inject_open_tabs.pyAfter running the main migration, tabs may only appear as bookmarks or metadata. To make them show up as real browser tabs in Zen's sidebar, run:
# Migrate with custom settings
python3 migrate_arc_to_zen.py --zen-profile "Default" --verboseThis writes directly to zen-sessions.jsonlz4, which is the file Zen actually
reads to render tabs. The script is idempotent β re-running it replaces
previously-injected tabs with a fresh extraction.
For open tabs, zen-sessions.jsonlz4 alone is NOT enough. Zen keeps two
session files in lockstep, matched per-tab by zenSyncId:
zen-sessions.jsonlz4β Zen's workspace tab store (flat list)sessionstore.jsonlz4/sessionstore-backups/recovery.jsonlz4β the regular Firefox session
On startup Zen effectively keeps the intersection: an open tab survives only
if a tab with the same zenSyncId exists in BOTH files. Tabs written to only
one file are silently pruned on the next restart.
inject_open_tabs.py handles this: it appends the same tab object (same
zenSyncId) to both files (plus recovery.jsonlz4), maps Arc spaces to Zen
workspaces by name, infers the container id from the workspace's existing
tabs, dedups against URLs already present in either file, and creates
timestamped backups. Zen must be fully quit while it runs.
python3 inject_open_tabs.py --dry-run # preview what would be injected
python3 inject_open_tabs.py # inject into both session filesArc archives inactive tabs on a timer (12h/24h/7d/30d). restore_auto_archived.py
restores ONLY the tabs Arc closed by itself β archive items in
StorableArchiveItems.json with reason == "auto". Tabs closed manually
(reason == "manual", e.g. Cmd+W) are deliberately ignored. Each tab returns
to its original space (resolved via the archive item's source.space UUID) as
a real open tab, using the same dual-file mechanism as inject_open_tabs.py.
python3 restore_auto_archived.py --dry-run
python3 restore_auto_archived.py# Migrate only a specific Arc space
python3 migrate_arc_to_zen.py --arc-space "Personal"
python3 migrate_arc_to_zen.py --arc-space "Work" --dry-run
# Specify Zen profile
python3 migrate_arc_to_zen.py --zen-profile "Default"
# Also migrate open tabs via sessionstore (legacy approach)
python3 migrate_arc_to_zen.py --open-tabs
# Verbose logging
python3 migrate_arc_to_zen.py --verbose
# See all available options
python3 migrate_arc_to_zen.py --help- Arc Spaces β Zen Workspaces (each Arc space becomes a Zen workspace)
- Space Icons β Workspace Icons (Unicode emojis preserved: π , π³, π¬, βοΈ, etc.)
- Space Colors β Workspace Themes (Arc's subtle color tints accurately reproduced)
- Pinned Tabs β Zen Pinned Tabs (with folder structure preserved)
- Essential Tabs β Essential Pinned Tabs (Arc's top toolbar tabs with large icons)
- Open Tabs β Zen Open Tabs (unpinned tabs restored as real browser tabs)
- Folder Hierarchy β Zen Folder Structure (nested folders maintained)
- Display Order β Zen Sidebar Order (Arc visual ordering preserved)
- Backup Bookmarks β Firefox Bookmarks (additional backup as standard bookmarks)
The tool reads Arc's StorableSidebar.json to extract:
- Space names, structure, and icons (Unicode emojis when available)
- Pinned tabs with URLs and metadata
- Open (unpinned) tabs per space
- Folder hierarchy within each space
- Visual ordering using container childrenIds
The tool helps you map Arc spaces to Zen workspaces:
python3 src/zen_workspace_mapper.pyThis creates a mapping guide showing which Zen workspace UUID corresponds to each Arc space.
For Zen 1.18+, spaces, pinned tabs, and folders are written directly to zen-sessions.jsonlz4 β the modern storage format for Zen's sidebar. For older Zen versions, the tool falls back to the legacy zen_pins and zen_workspaces SQLite tables.
- Read-only Arc access - Your Arc data is never modified
- Automatic backups - Zen database is backed up before any changes
- Dry-run mode - Test migration without making changes
- Validation - Data integrity checks throughout the process
arc2zen/
βββ migrate_arc_to_zen.py # Main migration script
βββ inject_session_tabs.py # Inject pinned tabs/folders into zen-sessions.jsonlz4
βββ inject_open_tabs.py # Inject open tabs into BOTH session files (Zen 1.20+)
βββ restore_auto_archived.py # Restore Arc auto-archived tabs (reason=auto)
βββ requirements.txt # Python dependencies (lz4)
βββ src/
β βββ arc_pinned_tab_extractor.py # Extract Arc pinned tabs
β βββ arc_bookmark_extractor.py # Extract Arc bookmarks
β βββ arc_profile_discovery.py # Locate Arc profiles
β βββ zen_sessions_importer.py # Import to zen-sessions.jsonlz4 (Zen 1.18+)
β βββ zen_sessionstore_manager.py # Read/write mozlz4 sessionstore
β βββ zen_pinned_tab_importer.py # Legacy: import tabs to zen_pins table
β βββ zen_workspace_importer.py # Legacy: create zen_workspaces entries
β βββ zen_space_importer.py # Create Zen containers for spaces
β βββ zen_bookmark_importer.py # Backup import as Firefox bookmarks
β βββ zen_workspace_mapper.py # Map Arc spaces to Zen workspaces
β βββ zen_schema_analyzer.py # Analyze Zen database schema
βββ .gitignore # Excludes generated files
βββ README.md # This file
Before running the full migration, you may want to map your Arc spaces to Zen workspaces:
python3 src/zen_workspace_mapper.pyThis interactive script will:
- Analyze your current Zen workspace structure
- Ask for your Arc space names (or detect them automatically)
- Create a mapping guide at
workspace_uuid_mapping.json - Show you which UUID corresponds to each workspace
You can also run individual components:
# Extract Arc pinned tabs only
python3 src/arc_pinned_tab_extractor.py
# Analyze Zen database schema
python3 src/zen_schema_analyzer.py
# Import pinned tabs to Zen (advanced usage)
python3 src/zen_pinned_tab_importer.py --dry-run--dry-run- Test migration without making changes--zen-profile NAME- Specify target Zen profile name--arc-space NAME- Migrate only a specific Arc space by name (case-insensitive partial matching). If not specified, all spaces are migrated.--verbose- Enable detailed debug logging--help- Show all available options
The tool creates several files during migration (all excluded from git):
arc_bookmarks_export.json- Extracted Arc pinned tabsarc_pinned_tabs_export.json- Arc pinned tabs with workspace infoworkspace_uuid_mapping.json- Mapping between Arc spaces and Zen workspaces*.backup.*- Database backups
β Improved: The migration tool preserves Arc's visual ordering using Arc's internal container structure.
Technical Solution: Arc stores display order in each space's pinned container childrenIds array, which contains items in visual order. The migration tool uses this data structure to maintain ordering fidelity.
Result: Folders and tabs appear in Zen in a similar order to your Arc sidebar.
β Implemented: Arc space icons migrate to Zen workspaces as Unicode emojis.
Technical Solution: Extracts Unicode emojis from Arc's customInfo.iconType.emoji_v2 field and preserves them in Zen workspace definitions.
Result: Arc space icons (π , π³, π¬, βοΈ, etc.) appear as visual icons in Zen workspaces.
β Implemented: Arc space colors migrate as subtle workspace themes with pixel-perfect accuracy.
Technical Solution:
- Extracts RGB values from Arc's
customInfo.windowTheme.primaryColorPalette.midTone - Uses measured Arc color values (e.g., Personal green: #bbf6da, WillowTree gold: #fbe496)
- Applies Arc's exact color transformation algorithm to create matching subtle tints
- Stores as JSON theme data in Zen's workspace theme system (
theme_type,theme_colors)
Result: Zen workspace backgrounds closely match Arc's subtle color aesthetics.
β Implemented: Arc's Essential tabs (top toolbar) migrate to appropriate workspaces.
Technical Solution:
- Extracts Essential tabs from Arc's
topAppscontainers per profile - Maps tabs to correct workspaces using profile associations (
directoryBasename) - Imports with
is_essentialflag to distinguish from regular pinned tabs
Result: Arc's Essential tabs appear as pinned tabs in their respective Zen workspaces.
- Arc's custom folder icons/colors are not preserved (Zen uses its own folder styling)
- All folder hierarchy and content relationships are maintained
- Arc-specific features (like Boosts, Easels) don't have Zen equivalents and are not migrated
- Standard web content, bookmarks, and organizational structure migrate completely
- Space icons: Arc space emojis migrate as Unicode icons in Zen
- Space colors: Arc color themes migrate as Zen workspace themes
- Essential tabs: Arc's top toolbar tabs migrate to appropriate workspaces
- Display ordering: Arc sidebar ordering preserved via container childrenIds
- Folder hierarchy: Nested folder structure maintained
- Workspace mapping: Arc space β Zen workspace conversion
"Zen profile not found"
- Make sure Zen browser has been run at least once
- Check that the profile directory exists at
~/Library/Application Support/zen/Profiles/
"No Arc data found"
- Verify Arc browser is installed
- Check that you have spaces with pinned tabs
Workspace mapping issues
- Run
python3 src/zen_workspace_mapper.pyto manually map spaces - Update the generated
workspace_uuid_mapping.jsonfile
If anything goes wrong:
- The tool creates automatic backups of your Zen database
- You can restore from the
.backupfiles - Your Arc data remains unchanged (read-only access)
- Location:
~/Library/Application Support/Arc/(macOS) - Format: Chromium-based with Arc-specific extensions
- Key File:
StorableSidebar.jsoncontains spaces, pinned tabs, and folder hierarchy - Container ordering: Each space has
containerIDs: ['pinned', uuid, 'unpinned', uuid]where the UUID immediately following each marker stores that category'schildrenIdsin exact visual order. The marker order can vary (pinned-first or unpinned-first).
- Location:
~/Library/Application Support/zen/Profiles/[profile]/(macOS) - Format: Firefox-based
- Key Files:
zen-sessions.jsonlz4(Zen 1.18+: spaces, pinned tabs, folders)sessionstore.jsonlz4+sessionstore-backups/recovery.jsonlz4(Firefox session; on Zen 1.20+ open tabs must also exist here with a matchingzenSyncIdβ see "Dual-File Injection" above)places.sqlite(bookmarks database)containers.json(workspace container definitions)prefs.js(preferences)
- Zen 1.18+:
zen-sessions.jsonlz4β mozlz4-compressed JSON containing spaces, tabs, and folders - Legacy Zen:
zen_pinsandzen_workspacesSQLite tables inplaces.sqlite - Bookmarks: Standard Firefox
moz_bookmarks/moz_placestables (used as backup)
Contributions are welcome! This is an open source tool for the community.
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
Always test with dry-run first:
python3 migrate_arc_to_zen.py --dry-run --verboseMIT License - See LICENSE file for details.
- Arc Browser team for creating an innovative browser
- Zen Browser team for building a privacy-focused alternative
- The open source community for inspiration and tools
- Claude Code for AI-assisted development and debugging