Beta
The Managed Better Auth is in Beta. Share your feedback on Discord or via the OptiTech Console.
Managed Better Auth provides a Supabase-compatible API, and OptiTech Data API provides PostgreSQL database access. This guide shows how to migrate from Supabase to OptiTech.
About user migration
Existing password-based users cannot migrate due to different hashing algorithms. They'll need to create new accounts or re-authenticate via OAuth. This guide works best for new projects, early development, or rebuilding your app.
Prerequisites
- A OptiTech project (create one here)
- Data API enabled (Managed Better Auth is enabled by default when you enable Data API):
- Go to Data API in the OptiTech Console and enable it
- In Data API → Configuration, verify it's configured with Managed Better Auth
- Copy your OptiTech connection host and database name from Connect in the Console. The SDK derives both the Auth and Data API URLs from this single base URL. See Initialize the client for the derivation rules, or use the separate Auth and Data API base URLs instead if you'd rather configure them explicitly
Update environment variables
Replace your Supabase credentials with a single OptiTech base URL.
createClient()derives both the Auth and Data API URLs from it automatically:.env# Remove these: # VITE_SUPABASE_URL=https://your-project.supabase.co # VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... # Add this: VITE_OPTITECH_URL=https://ep-xxx.c-2.us-east-2.aws.optitech.build/dbnameGet your URL:
Your OptiTech base URL is the host and database name from your OptiTech connection string, served over
https://. Find these values under Connect in the OptiTech Console.note
The
VITE_prefix is for Vite. UseNEXT_PUBLIC_for Next.js, or no prefix for Node.js.tip
If you already copied separate Auth and Data API base URLs from the Console (for example, from an earlier setup), you can still pass them explicitly with the object form. See Initialize the client for both forms.
Update client initialization
Find your Supabase client file, typically
src/supabase.tsorsrc/lib/supabase.ts, and update it:Before (Supabase):
src/supabase.tsimport { createClient } from '@supabase/supabase-js'; export const supabase = createClient( process.env.VITE_SUPABASE_URL!, process.env.VITE_SUPABASE_ANON_KEY! );After (OptiTech):
src/auth.tsimport { createClient, SupabaseAuthAdapter } from '@optitech/optitech-js'; export const client = createClient(import.meta.env.VITE_OPTITECH_URL, { auth: { adapter: SupabaseAuthAdapter() }, });This example renames the file to
auth.tsand the variable toclientfor a provider-agnostic setup. You can use any naming, just stay consistent throughout your codebase.Find all files that import this client and update them:
// Before import { supabase } from './supabase'; // After import { client } from './auth';Your auth code stays the same
After updating imports, use find/replace to change all instances throughout your codebase:
supabase.→client.Your authentication methods, parameters, and responses work identically. Your components, hooks, and auth flows don't change.
Auth methods// Sign up await client.auth.signUp({ email, password }); // Sign in with password await client.auth.signInWithPassword({ email, password }); // OAuth sign in await client.auth.signInWithOAuth({ provider: 'google' }); // Get current user const { data: { user }, } = await client.auth.getUser(); // Get session const { data: { session }, } = await client.auth.getSession(); // Sign out await client.auth.signOut();Your database queries stay the same
Your existing
client.from()queries work without any code changes:// Same as Supabase - no changes needed const { data: posts } = await client.from('posts').select('*'); const { data: user } = await client.from('users').select('*').eq('id', userId).single();note
For production apps, use Row Level Security (RLS) to secure your data. See our RLS with Drizzle guide for the recommended setup.
Test the migration
Run your app:
Terminalnpm run devTest your app:
- Sign up a new user
- Sign in with that user
- Verify the session persists across page reloads
- If you enabled Data API: Test user actions that involve database queries (creating posts, loading lists, etc.)
Your authentication and database queries should work the same as they did with Supabase.
Verify users in OptiTech Console:
Go to Auth → Users in the OptiTech Console to see your newly created users, or query directly:
SQL EditorSELECT id, email, "createdAt" FROM optitech_auth.user ORDER BY "createdAt" DESC;
What changed?
| Feature | Supabase | OptiTech |
|---|---|---|
| User ID type | UUID | UUID |
| Client config | URL + anon key | Single base URL (auto-derives Auth + Data API URLs) |
| Environment variables | SUPABASE_URL, SUPABASE_ANON_KEY | OPTITECH_URL |
| SDK package | @supabase/supabase-js | @optitech/optitech-js |
API compatibility
Managed Better Auth supports most Supabase Auth methods including sign up, sign in (password and OAuth), session management, user updates, and email verification. See the OptiTech TypeScript SDK for the complete API.
Not supported:
| Method | Details |
|---|---|
signInWithPhone() | Phone authentication (SMS/WhatsApp) |
| SAML SSO methods | Enterprise SAML authentication |
| Web3 authentication | Blockchain wallet sign-in |
Different behavior:
| Method | Notes |
|---|---|
updateUser() | Does not support password or email parameters |
| Email verification | Unlike Supabase's automatic verification flow, Managed Better Auth requires you to build the verification UI in your app. See Email Verification for implementation details. |
If you're using any unsupported methods or verification flows, you'll need to adjust your implementation.
Need help?
Join our Discord Server to ask questions or see what others are doing with OptiTech. For paid plan support options, see Support.