Skip to main content
Percher is still being built and account creation is paused — get notified when it opens.

Migrating from Supabase

Keep Supabase or switch to PocketBase

Ask your agent
Plan how to move my Supabase app to Percher. Inventory its database, auth, storage, functions, and secrets first; keep the existing app working until I approve the cutover.Read the guide at percher.app/docs/migrate-supabase
Keep my Supabase, but host the app on Percher.Read the guide at percher.app/docs/migrate-supabase
How it works, with exact details

Two options: keep using your Supabase project as an external database, or switch to Percher's managed PocketBase. For most apps — and anything that leans on Postgres features — Option 1 is the right call.

Option 1: Keep Supabase (recommended, no rewrite)

# percher.toml
[data]
mode = "supabase"

[data.supabase]
url = "https://your-project.supabase.co"
anon_key = "eyJ..."

# No code changes needed — your existing Supabase client keeps working.
# SUPABASE_URL and VITE_SUPABASE_URL are injected automatically.

This works for every Supabase app — you keep Postgres, RLS, auth, storage, edge functions, realtime, and pgvector exactly as they are. Percher just hosts the app.

Option 2: Switch to PocketBase

Percher generates most of the migration for you. It writes a ./migration-preview/ folder — nothing touches your data until you run the scripts yourself.

bunx percher migrate-from-supabase --project <ref> --token sbp_...
#  → migration-preview/pb_schema.json    tables → PocketBase collections
#  → migration-preview/pb_migrate.js     runnable data-import script (copies your rows)
#  → migration-preview/MIGRATION_NOTES.md every RLS policy + manual step

# Also convert your Supabase SDK calls to the PocketBase SDK:
bunx percher migrate-from-supabase --project <ref> --token sbp_... --rewrite-client
#  preview first; add --apply to write in place (originals are backed up)
#  scaffolds src/lib/pocketbase.ts + inserts imports; auth recipes in REWRITE_NOTES.md

# See what's still on Supabase vs PocketBase (local scan, no token):
bunx percher migrate-from-supabase --status

Honest limits — read before committing

  • Auth users can't be moved directly. Supabase password hashes aren't compatible with PocketBase — every user has to reset their password.
  • It's a preview plus a script, not one click. You run the data-import yourself with a Supabase service-role key and review the flagged items.
  • Some things don't port at all: Edge Functions, Postgres views/triggers/functions, complex RLS (the tool translates the simple auth.uid() = column case and flags the rest), realtime, PostGIS, and pgvector. If your app depends on these, keep Supabase (Option 1).

Concept mapping for the parts you rewrite by hand:

supabase.from('table').select()pb.collection('table').getList()
supabase.from('table').insert({})pb.collection('table').create({})
supabase.from('table').update({})pb.collection('table').update(id, {})
supabase.from('table').delete()pb.collection('table').delete(id)
supabase.auth.signUp()pb.collection('users').create({})
supabase.auth.signInWithPassword()pb.collection('users').authWithPassword()
supabase.auth.getUser()pb.authStore.record
supabase.storage.upload()pb.collection('x').create(formData)
supabase.channel().subscribe()pb.collection('x').subscribe('*', fn)
Row Level Security (SQL policies)PocketBase API rules (per collection)
.select('*, posts(*)')pb.getList({ expand: 'posts' })