docs/self-hosting/migration/v2/auth/clerk-to-betterauth.mdx
This guide helps you migrate your existing Clerk-based LobeHub deployment to Better Auth.
<Callout type={'info'}> Better Auth is the recommended authentication solution for LobeHub. It offers simpler configuration, more SSO providers, and better self-hosting support. </Callout>
<Callout type={'error'}> Important Notice:
| Method | Best For | User Impact | Data Preserved |
|---|---|---|---|
| Simple Migration | Small deployments (≤ 10 users) | Users reset passwords | Chat history, settings |
| Full Migration | Large deployments | Seamless for users | Everything including passwords |
For small self-hosted deployments, the simplest approach is to let users reset their passwords.
<Callout type={'warning'}> Limitation: This method loses SSO connection data. Use Full Migration to preserve SSO connections.
Although SSO connections are lost, users can manually re-link their social accounts from the Profile page after logging in with email and password.
Example scenario: If your previous account had two SSO accounts linked:
[email protected][email protected]After migrating and resetting password with [email protected], logging in with [email protected] will create a new user instead of linking to your existing account.
</Callout>
Configure Email Service
Set up email service for password reset functionality. See Email Service Configuration.
Update Environment Variables
Remove Clerk variables and add Better Auth variables:
<GenerateSecret envName="AUTH_SECRET" /># Remove these
# NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=xxx
# CLERK_SECRET_KEY=xxx
# Add these
AUTH_SECRET=your-secret-key # openssl rand -base64 32
# Optional: Enable Google SSO (example)
AUTH_SSO_PROVIDERS=google
AUTH_GOOGLE_ID=your-google-client-id
AUTH_GOOGLE_SECRET=your-google-client-secret
<Callout type={'tip'}> See Authentication Service Configuration for complete environment variables and SSO provider setup. </Callout>
Redeploy LobeHub
Deploy the new version with Better Auth enabled.
Notify Users
Inform users to follow these steps to log in (chat history and settings will be preserved):
https://your-domain.com/signin)If Magic Link is enabled: The system will automatically send a login link email. Users can click the link to log in directly.
If Magic Link is not enabled: The page will display a hint message. Users can either:
<Callout type={'tip'}> This method is quick and requires minimal setup. Users can log in via Magic Link, social accounts, or by setting a new password. All data remains intact. Users can manage their password and linked accounts anytime in the Profile page. </Callout>
For larger deployments or when you need to preserve user passwords and SSO connections, use the migration scripts.
<Callout type={'error'}> Important Notice:
Environment Requirements:
Preparation:
Clone the LobeHub repository and install dependencies:
git clone https://github.com/lobehub/lobehub.git
cd lobehub
pnpm install
Prepare the following information:
Ensure database schema is up to date
<Callout type={'info'}> If you've been on an older version (e.g., 1.x) for a while, your database schema may be outdated. Run this in the cloned repository:
DATABASE_URL=your-database-url pnpm db:migrate
Create a .env file in the project root (the script will automatically load it) with all environment variables:
# ============================================
# Migration mode: test or prod
# Recommended: Start with test mode to verify on a test database,
# then switch to prod after confirming everything works
# ============================================
CLERK_TO_BETTERAUTH_MODE=test
# ============================================
# Database connection (uses corresponding variable based on mode)
# TEST_ prefix for test environment, PROD_ prefix for production
# ============================================
TEST_CLERK_TO_BETTERAUTH_DATABASE_URL=postgresql://user:pass@test-host:5432/testdb
PROD_CLERK_TO_BETTERAUTH_DATABASE_URL=postgresql://user:pass@prod-host:5432/proddb
# ============================================
# Clerk API keys (for exporting user data via API)
# Get from Clerk Dashboard: Configure → Developers → API Keys
# ============================================
TEST_CLERK_TO_BETTERAUTH_CLERK_SECRET_KEY=sk_test_xxx
PROD_CLERK_TO_BETTERAUTH_CLERK_SECRET_KEY=sk_live_xxx
# ============================================
# Database driver (optional)
# neon: Neon serverless driver (default)
# node: node-postgres driver
# ============================================
CLERK_TO_BETTERAUTH_DATABASE_DRIVER=neon
# ============================================
# Dry Run mode (optional)
# Set to 1 to only print logs without modifying the database
# Recommended: Enable for first run, disable after verification
# ============================================
CLERK_TO_BETTERAUTH_DRY_RUN=1
Before exporting data, disable new user registration to ensure data consistency during migration:
scripts/clerk-to-betterauth/test/clerk_exported_users.csvSee Clerk documentation for details.
# Run export script (automatically selects key and output path based on CLERK_TO_BETTERAUTH_MODE)
npx tsx scripts/clerk-to-betterauth/export-clerk-users-with-api.ts
This automatically creates scripts/clerk-to-betterauth/test/clerk_users.json with additional user data.
# Run migration (CLERK_TO_BETTERAUTH_DRY_RUN=1, only logs without modifying database)
npx tsx scripts/clerk-to-betterauth/index.ts
Review the output logs, confirm no issues, then proceed to the next step.
Update .env to set CLERK_TO_BETTERAUTH_DRY_RUN to 0, then execute:
# Execute migration
npx tsx scripts/clerk-to-betterauth/index.ts
# Verify the migration
npx tsx scripts/clerk-to-betterauth/verify.ts
After verifying the test environment migration is successful, proceed to the next step.
scripts/clerk-to-betterauth/prod/clerk_exported_users.csv.env file:
CLERK_TO_BETTERAUTH_MODE to prodCLERK_TO_BETTERAUTH_DRY_RUN back to 1# Export production user data
npx tsx scripts/clerk-to-betterauth/export-clerk-users-with-api.ts
# Run migration (dry-run mode to verify)
npx tsx scripts/clerk-to-betterauth/index.ts
Review the output logs, confirm no issues, then proceed to the next step.
Update .env to set CLERK_TO_BETTERAUTH_DRY_RUN to 0, then execute:
# Execute migration
npx tsx scripts/clerk-to-betterauth/index.ts
# Verify the migration
npx tsx scripts/clerk-to-betterauth/verify.ts
After migration is complete, follow Simple Migration - Step 2 to configure Better Auth environment variables and redeploy.
<Callout type={'tip'}> For complete Better Auth configuration, see Authentication Service Configuration. </Callout>
| Data | Simple Migration | Full Migration |
|---|---|---|
| User accounts | ✅ (via password reset) | ✅ |
| Password hashes | ❌ | ✅ |
| SSO connections (Google, GitHub, etc.) | ❌ | ✅ |
| Two-factor authentication | ❌ | ✅ |
| Chat history | ✅ | ✅ |
| User settings | ✅ | ✅ |
After migration, if you encounter login issues, try clearing your browser's site data first:
AUTH_SECRET is set correctlyAUTH_SSO_PROVIDERSThis error occurs because the database schema is outdated. Run pnpm db:migrate to update the database structure before running the migration script.
<Card href={'/docs/self-hosting/auth'} title={'Authentication Service Configuration'} />
<Card href={'/docs/self-hosting/environment-variables/auth'} title={'Auth Environment Variables'} />
<Card href={'/docs/self-hosting/auth/legacy'} title={'Legacy Authentication (NextAuth & Clerk)'} /> </Cards>