Open-source toolset (espinosacodes) to migrate your browser logins and your active signed-in state (sessions) between browsers and machines, without losing either. Everything stays on your machine, nothing is uploaded anywhere.
macOS Firefox -> browser-sync -> Fedora Firefox (or Chrome/Brave/etc.)
npm: command published under
@espinosacodes/browser-sync.
npm install -g @espinosacodes/browser-syncThat installs the browser-sync command on macOS, Windows, or Linux (your Mac
and your Fedora laptop both). Runs on Node 14+. No Python required.
Requirements (one line): Node.js 14+ on each machine.
Or run it without installing (no global install needed):
npx @espinosacodes/browser-sync --helpOr clone the source from github.com/espinosacodes/browser-sync and build:
git clone https://github.com/espinosacodes/browser-sync.git
cd browser-sync
npm install && npm run build
node dist/index.js --helpbrowser-sync selfcheck
# selfcheck OK: 3 input rows merged to 2, longest password kept, output writtenIf that prints OK, the tool is working. (It is tested on every release via this self-check.)
browser-sync merge firefox.csv chrome.csv -o for-fedora.csv # saved logins
browser-sync carry --to /tmp/session-carry # active signed-in sessionsTwo commands:
-
browser-sync mergemoves saved logins (usernames + passwords) as CSV across Firefox / Chrome / Edge / Brave / Vivaldi / Opera / Bitwarden. -
browser-sync carrycopies your "already signed in" sessions (cookies + keys) from one Firefox profile to another machine's Firefox.
If what you want is: on the new machine you are already signed into GitHub, Gmail, AWS, etc., exactly like on your Mac, that is cookies, and this is the command you want.
# On your Mac, with Firefox fully closed:
browser-sync carry --to /tmp/session-carry # use --dry-run first to preview
# -> copies cookies.sqlite, key4.db, cert9.db into /tmp/session-carry
# Move that folder to the Fedora machine (USB/email), then there:
browser-sync carry --src /tmp/session-carry --to ~/.mozilla/firefox/<profile>.default-releasecookies.sqlite holds the session data, key4.db the encryption keys, and
cert9.db the certificates. They must move together. Firefox must be closed on
both ends while copying.
What to expect: many sites (Google, banking, SSO) detect a new device/IP and force a fresh sign-in on first use. That is enforced by the website, not by this tool, and cannot be bypassed. Sites without that check carry over fully signed-in.
Passwords/logins are intentionally NOT moved by carry; use merge for those.
| Browser | Path |
|---|---|
| Firefox | Menu -> Logins and Passwords -> ... (ellipsis) -> Export Logins... |
| Chrome | Settings -> Autofill and passwords -> Google Password Manager -> Settings -> Export passwords |
| Edge | Settings -> Profiles -> Passwords -> (three dots) -> Export passwords |
| Brave / Vivaldi / Opera | Settings -> Passwords -> Export (like Chrome) |
| Bitwarden | Vault -> options -> Export vault (csv) |
You get a .csv file. Keep it somewhere safe; it is your passwords in plain text.
browser-sync merge firefox.csv -o for-linux.csv
# or combine exports from many browsers:
browser-sync merge firefox.csv chrome.csv edge.csv -o for-linux.csv
# or export for a Bitwarden vault:
browser-sync merge firefox.csv --to bitwarden -o bw.csvIt auto-detects each source (Firefox vs Chrome-family vs Bitwarden), drops empty rows, collapses duplicate logins across sources (same site + username = one entry, keeps the longest password), and writes one clean CSV.
Copy the CSV to the new machine, then in the target browser:
Settings -> Passwords -> Import... and pick the file. Done.
Firefox / Chrome / Edge / Brave / Vivaldi / Opera / Bitwarden all accept the
name,url,username,password header emitted by default.
- Firefox's extra columns (
httpRealm,formActionOrigin) vs Chrome/Brave's barename,url,username,password, vs Bitwarden's vault schema. - Cross-browser duplicates: the same GitHub login saved in both Firefox and Chrome collapses to one row.
- Sites Google leaves bare (e.g.
mail.google.com) stay usable.
The project is tested. npm run build then node dist/index.js selfcheck
exercises the merge/carry logic directly against sample CSVs and temp profiles;
a correct result fails the build. The legacy make selfcheck runs all three
suites (the TypeScript CLI plus the Python twins).
npm run build && npm run selfcheck # TypeScript CLI (primary, ships to npm)
make selfcheck # all suites: TS CLI + Python twinsThese run automatically on npm publish (via prepublishOnly), so every
published version is verified.
package.json npm package (@espinosacodes/browser-sync), TypeScript build
cli/index.ts the entire CLI in TypeScript (merge + carry), zero runtime deps
dist/index.js compiled output shipped to npm (generated by `npm run build`)
browser_sync.py legacy Python twin of `merge`
carry_session.py legacy Python twin of `carry`
extension/ optional browser extension that captures NEW logins as you type
them (cannot reach already-saved passwords), see extension/README
LICENSE MIT
The package is written in TypeScript; npm run build compiles cli/index.ts
to dist/index.js (npm runs the compiled JS).
- This tool never sends data off your machine. It reads and writes local files.
- Handle exported CSV files carefully; they contain plaintext passwords.
- The optional extension keeps captured logins in local browser storage only; no cloud by default.
- Core CSV migration + dedupe across browsers and OSes
- Bitwarden export format
- Carry active sessions (cookies) between machines
- GUI (drag-and-drop a CSV, pick target, get clean file)
- Optional Google OAuth to sync a captured-vault file across your machines
- Native Firefox extension that wraps export/import in one click
MIT (c) 2026 espinosacodes. Open source, free to fork.