30. Migrating from Supabase (FAQ)

Common questions from teams moving an existing Supabase project to Eurobase — what ports cleanly, what needs a rewrite, and where we're honest about the differences.

Eurobase is close to Supabase in shape — Postgres, Row-Level Security, an SDK with a familiar API, EU storage with signed URLs — but it is not a drop-in replacement. A migration CLI (eurobase import supabase) automates most of a move, starting with an assess step that reports what transfers cleanly and what needs changes. It's rolling out now — get in touch and we'll run an assessment against your project. The answers below are deliberately straight about the gaps.

Migrating in

Can I import my existing users without password resets?

Yes. We use bcrypt in the same format as Supabase, so password hashes import as-is and your users keep their passwords. The importer preserves user UUIDs (so RLS keeps working), email-confirmed status, metadata, and OAuth identities. Without the CLI, the users API's batch import takes the same bcrypt hashes and ids (see below).

Can I keep using supabase-js?

No — you switch to @eurobase/sdk. It is not wire-compatible, but the API shape is deliberately familiar (createClient, auth.signUp, .from(), .rpc(), .storage), so for a typical app it is a contained change.

Can I run a trial alongside my current setup?

Yes. Your account can have up to 10 projects on Pro, so you can stand up a test project next to your live backend and trial the migration before switching anything.

Database & auth differences

Is Row-Level Security supported?

Yes — RLS is the core authorization model, with the same helpers you know (auth.uid(), auth.role(), auth.email(), is_service_role()). The importer auto-translates Supabase policies, and the service (secret) key bypasses RLS like Supabase's service role.

Are SECURITY DEFINER functions supported?

Not on self-serve surfaces — this is the biggest difference to plan for. Re-express them as plain (invoker) functions plus RLS, as server-side code using the service key, or as edge functions. Plain functions and trigger functions port fine.

Does the trigger on auth.users (profile-on-signup) pattern work?

No — the users table is platform-managed, so you can't attach a trigger to it. You can still reference it (REFERENCES users(id)) and read it server-side. Create the profile row in your signup code or an edge function; list and delete users through the admin API.

How do I see the source of a database function?

Click it under Cron & RPC → Functions, or run eurobase functions get <name>. You get the full CREATE OR REPLACE FUNCTION statement; edit and run it in the SQL editor to change the function. pg_get_functiondef() and other system-catalog queries are refused in your own SQL. See Cron & RPC.

Can I send auth emails (reset, magic link) to my own site, with my own templates and sender?

Redirect URLs to your own app are fully configurable (allow-listed, same idea as Supabase's site URL). Custom email templates are available on Pro. A custom SMTP sender is a Pro feature we're finalising — validate your provider in a test project before relying on it.

Private storage with signed URLs?

Yes — a private per-project EU bucket with signed download URLs. Access differs from Supabase's storage.foldername() policies: files are owned per end-user automatically, with a separate mechanism for developer-shared folders (authenticated or public). SDK signed-URL expiry caps at 1 hour, so long playback sessions re-issue the URL.

Auth from your server

Can I create or import users from my server, e.g. with their email already confirmed?

Yes, with the users API and a project token with the Admin role (not the secret key — there's no /v1/auth/admin). POST /platform/projects/<id>/users creates one user; POST …/users/batch imports up to 500 per request. The password is optional (users then sign in by magic link or set one with a password reset), email_confirmed defaults to true, and a batch can carry bcrypt password_hashes and keep existing user ids. Re-running an import is safe. See Managing End Users.

Can I fetch, list, change and delete users from my server?

Yes, the same API: GET …/users?email= (exact) or ?search=, a list with last_sign_in_at and email_confirmed_at, PATCH …/users/<id> to change the email, name, metadata or confirmation, DELETE, suspend and reset password.

Can I verify access tokens on my server without a network call?

Yes. Access tokens are ES256-signed with your project's own key pair; the public key is at https://your-project.eurobase.app/v1/auth/.well-known/jwks.json. Verify with any JWT library that supports JWKS (issuer eurobase, audience = your project ID); see chapter 6 for an example. A locally verified token stays valid until it expires, so use GET /v1/auth/user where you need to confirm the user still exists and read their current profile.

With email confirmation on, users who haven't confirmed get "invalid email or password". Why?

That changed: signing in with the right password before confirming now answers 403 email_not_confirmed (SDK: EMAIL_NOT_CONFIRMED), so you can offer resendVerification(email). Sign-up returns no session until the user confirms. Whether a user has confirmed is in email_confirmed_at. Use @eurobase/sdk 0.10.0 or later with this setting.

Can a signed-in user change their password?

Yes: POST /v1/auth/user/password with current_password and new_password and the user's access token. Their other sessions end once their current access token expires, and the response is a fresh session. An SDK helper (updatePassword) needs @eurobase/sdk 0.11.0 or later.

What rate limits should I set for a launch or migration day?

When many users sign up or sign in at once, raise sign-ups / sign-ins to 30 and token verifications (which include magic-link sign-ins) to 150 per 5 minutes under Auth → Rate Limits beforehand. See Rate Limits.

Is there an hourly limit on auth emails with the built-in sender?

No hourly cap on the number of emails sent. Per address: 3 magic links and 3 password-reset emails per 15 minutes, and one verification resend per 5 minutes. Per client IP: 60 password-reset and 60 verification emails an hour, and 300 magic-link requests an hour. For a migration day, magic links (300/h) go further than mass password resets (60/h).

Reliability, backups & leaving

What backups and uptime do I get?

The managed database is backed up automatically about every 24 hours at the infrastructure level on every tier (worst-case data loss ≈ 24 hours). Customer-controlled backups and self-serve restore are a Team-tier feature (dedicated EU database). Pro carries a 99.5% monthly availability target — see the SLA for the full detail.

Do you provide a DPA and a sub-processor list?

Yes — an auto-generated DPA report per project, and a published, EU-only sub-processor list (Scaleway for compute/database/storage/email in France, Mollie for payments, GatewayAPI for SMS). See the Compliance chapter.

What happens to my data if Eurobase shuts down?

If we cease operations, we keep the Service and your data online and exportable for at least 90 days before any deletion, with email notice to project owners. Your data is portable at any time regardless: export your schema, all table data, and a storage manifest from the console or API.

Everything runs in the EU on Scaleway (France) — database, storage, and custom Go auth services — end to end, under EU jurisdiction. That data-sovereignty guarantee is the main reason most teams make this move.