FireMigrate: leave Firebase for Postgres without dumping everything into JSON

Leader ●1 ●2 ●8
calendar_today • schedule3 min read

It’s a small MIT CLI. The interesting work is still open.

Most Firebase → Postgres guides do the same thing: export the project, stuff documents into a jsonb column, call it migrated. You kept the data and lost the shape.
FireMigrate does the opposite. It reads Firestore and Firebase Auth first, prints a relational schema you can argue with, and refuses to write until you say so.

npx @ezekielreu6/firemigrate init
npx @ezekielreu6/firemigrate inspect
npx @ezekielreu6/firemigrate schema
npx @ezekielreu6/firemigrate migrate --dry-run

Website
npm
Repo

Why this exists
Firestore is a document store. Postgres is tables, types, and foreign keys. A real move has to admit uncertainty:
this field is a string in 80 documents and a number in 4
this userId looks like a reference
this collection has nested subcollections the sample never saw
FireMigrate treats those as warnings, not as something to hide in JSON.
What it does today
The package on npm is @ezekielreu6/firemigrate (currently 0.1.3). MIT. CLI-first. Node 20+.
Command

What actually happens

init
Writes firemigrate.config.json and .env.example. Will not overwrite unless you pass --force.
inspect
Read-only. Collection counts, sampled field types, mixed-type warnings, Auth provider summary.
schema
Prints Postgres SQL. One table per top-level collection. Mixed/maps/arrays → jsonb. Timestamps → timestamptz.
migrate --dry-run
Default. Streams documents, reports counts, writes nothing.
migrate --write
Only if the flag and "dryRun": false are set. Creates tables, upserts by id in batches, then checks row counts.

verify

Compares Postgres row counts to Firestore document counts.
Credentials live in env vars (FIREBASE_PROJECT_ID, FIREBASE_CLIENT_EMAIL, FIREBASE_PRIVATE_KEY, DATABASE_URL). The config file starts empty on purpose. Do not commit service-account keys.
What is still sharp (this is the contributor pitch)
This is an early foundation, not a complete migration product. That is the point of the repo.
Open work, if you want a useful PR:
Subcollections — detected, not migrated. Need a mapping that becomes real tables instead of a JSON blob.
Better relationship guesses — name-based FKs should stay warnings until confidence is high. Improve the analyzer, don’t silently emit fake constraints.
Auth users — inspect already summarizes providers. Actual Auth → Postgres (no plaintext passwords) is unbuilt.
Storage — not covered.
Sample bias — schema is inferred from up to 100 docs/collection (max 1000). Fields outside the sample get dropped and reported. Smarter sampling would help.
Tests — domain tests for inspect/schema/migrate, with fake fixtures and no real credentials.
Docs of edge cases — mixed types, colliding id fields, paused writes, verify mismatches.
What we will not merge: a PR that writes to the destination by default, logs private keys, or fakes inspect output.

Repo shape

packages/core inspect, schema, migrate, verify
packages/cli the firemigrate binary
Local loop:
pnpm install
pnpm build
node packages/cli/dist/packages/cli/src/index.js inspect
Small PRs. One adapter or one workflow change at a time. Keep dry-run as the default.
If you only have 20 minutes
Run init + inspect on a throwaway Firebase project. File an issue with:
what the inspect report got wrong
a redacted collection shape (field names + types, not documents)
what you expected the schema to look like
That kind of issue is more useful than a star.
If you want to implement something, open the issue first so two people don’t build the same subcollection mapper.
FireMigrate is for people who are leaving Firebase on purpose, not for people who want a magic dump. If that sounds like work you already do, the repo is here:
Repo

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelski - Apr 23

The Sovereign Vault — A Comprehensive Guide to Protocol-Driven AI

Ken W. Algerverified - Jun 4

Merancang Backend Bisnis ISP: API Pelanggan, Paket Internet, Invoice, dan Tiket Support

Masbadar - Mar 13

From Prompts to Goals: The Rise of Outcome-Driven Development

Tom Smithverified - Apr 11

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelski - Mar 19
chevron_left
873 Points • 11 Badges
2Posts
5Comments
5Connections
A young dev shipping real products

Related Jobs

View all jobs →

Commenters (This Week)

4 comments
2 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!