Migrate to ichibase
Move an existing app into ichibase — your database schema, your data, and your end-user accounts — from Supabase, a generic Postgres (any host), MongoDB, MongoDB Atlas, or Firebase (Firestore + Firebase Auth). A guided wizard in the dashboard plus the @ichibase/cli do the work. Migration is available on Pro and Business plans.
jsonb). Pick the target in the wizard or with --target mongo|postgres. SQL → NoSQL is not supported.Source support at a glance
| Source | → Postgres | → MongoDB | Accounts & passwords |
|---|---|---|---|
| Supabase | Yes (1:1 schema + data) | — | Built-in: auth.users (bcrypt carries over) |
| Postgres (any host) | Yes (1:1 schema + data) | — | Bring-your-own-users mapping |
| MongoDB / Atlas | Yes (inferred tables) | Yes (1:1) | Bring-your-own-users mapping |
| Firebase Firestore | Yes (inferred tables) | Yes (1:1) | Firebase Auth export (scrypt carries over), or a users collection via bring-your-own-users |
“Bring your own users” means accounts stored in an ordinary table/collection are mapped into ichibase Auth field-by-field — see migrating auth & passwords.
How it works
The CLI runs on your machine, against your source. It reads your data and writes an ichibase migration bundle — a folder containing your schema, your rows/documents, and your users. Your source credentials never leave your computer. You then push the bundle to your project: each part uploads straight to object storage and a background job imports it. Nothing is destructive on the source.
A bundle is just files you can inspect before pushing:
bundle/
├─ manifest.json # source kind, target flavor, table/collection list
├─ schema.json # Postgres: tables, columns, types, keys, indexes, FKs
├─ data/
│ ├─ <table>.ndjson # one JSON row per line (Postgres target)
│ └─ mongo.archive # native mongodump archive (Mongo 1:1 target)
└─ auth.ndjson # users: id, email, tagged password hash, oauth linksBefore you start
- A Pro or Business project to import into. Its database flavor must match your chosen target — a Postgres target needs a Postgres-enabled project, a Mongo target a Mongo-enabled one. The wizard only offers targets your project actually has.
- Node 18+ and the CLI:
npm i -g @ichibase/cli. - For a Mongo 1:1 import,
mongodumpon yourPATH(ships with the MongoDB Database Tools). Postgres targets need no extra tools. - An owner token to push (skip if you drop the folder into the dashboard). Create one under Account → API keys and export it as
ICHIBASE_TOKEN.
1 · Extract a bundle
Pick the command for your source.
Supabase
Tables, data, and auth.users (passwords come across). Use the Session pooler connection string (Project Settings → Database → Connection string → Session pooler) — the direct db.<ref>.supabase.cohost is IPv6-only and won't resolve on most machines:
ichibase migrate supabase \
--conn "postgresql://postgres.<ref>:PASSWORD@aws-0-<region>.pooler.supabase.com:5432/postgres" \
--out ./bundleGeneric Postgres (any host)
Any reachable Postgres — RDS, Neon, Render, Cloud SQL, self-hosted. Schema + data come across; map accounts with the bring-your-own-users flags if they live in a table:
ichibase migrate postgres --conn "postgresql://user:pw@host:5432/dbname" --out ./bundleMongoDB / Atlas
Collections + documents. Default --target mongo is a 1:1 import (needs mongodump on your PATH); --target postgres reads every document and infers typed tables instead:
ichibase migrate mongodb --conn "mongodb://user:pw@host:27017" --db myapp --out ./bundle
ichibase migrate atlas --conn "mongodb+srv://user:pw@cluster.mongodb.net" --db myapp --target postgres --out ./bundleFirebase
Firestore documents + Firebase Auth. See the Firebase guide for the service-account key and password-hash parameters:
ichibase migrate firebase --service-account ./service-account.json --target mongo --out ./bundleauth.users or Firebase Auth), map them into ichibase Auth with --auth-table/--auth-collection plus --auth-email-field, --auth-pass-field and --auth-hash-scheme bcrypt|argon2|fbscrypt|plain|none. Full flag list in auth & passwords.2 · Push it to your project
Two ways, same result:
- Dashboard — open Database → Import / Migrate, choose your source and (for NoSQL) the target, then select the
bundlefolder. Parts upload to storage from your browser. - CLI — push the same folder headlessly:
ichibase migrate push --project <slug> --bundle ./bundle --token "$ICHIBASE_TOKEN"Either way you get a live progress view and a final report. The job runs in phases:
| Phase | What happens |
|---|---|
| validating | Manifest + bundle integrity checks; target flavor confirmed. |
| schema | Postgres: tables, columns, keys, indexes created (FKs deferred). |
| data | Rows (NDJSON) / documents (archive or per-collection) loaded. |
| auth | Users imported with original IDs + tagged password hashes. |
| verifying | Row/document/user counts compared against the bundle; FKs added. |
What gets migrated
- Schema(Postgres): tables, columns & types, primary keys, unique constraints, indexes, and foreign keys — recreated in your project's
publicschema. For NoSQL → Postgres the schema is inferred from your documents. - Data: every row (Postgres) / document (Mongo). Postgres foreign keys are added after load so insert order doesn't matter; identity/serial sequences are reset.
- Auth: users keep their original IDs and passwords — see how passwords migrate.
Troubleshooting
| Symptom | Fix |
|---|---|
| Supabase connect hangs / ENOTFOUND | Use the Session pooler host, not db.<ref>.supabase.co (IPv6-only). |
mongodump: command not found | Install the MongoDB Database Tools, or use --target postgres (no mongodump needed). |
| Target rejected on push | Your project lacks that DB. Pick the other --target, or enable the engine on the project. |
| Migrated tables return nothing with the anon key | Expected — RLS is on with no policies. Add policies; see Differences & gotchas. |
| A user can’t log in after migrating | Password hash scheme/params were wrong or unsupported — that user uses “forgot password”. |
