Migrate from Clerk

Migrate from Clerk

Clerk DX, Authio depth — without the per-org-per-MAU pricing tiers.

Clerk and Authio share a lot of the same data model: multi-org by default, identities live on the user (not the membership), email is the user identity. The Clerk importer maps the graph 1:1.

What you'll keep, what you'll lose, what you'll gain

  • Keep: All organizations and memberships at their original role; external accounts (Google/MS/etc.) as Authio identities; phone numbers, public/private metadata, profile images.
  • Lose: Clerk's prebuilt components (you switch to Authio's hosted UI or the Next.js / React SDK); Clerk sessions (users re-auth); bcrypt password hashes (Authio is passwordless).
  • Gain: Authio's risk engine with adaptive step-up. The audit stream. Predictable per-MAU pricing — without per-org tier upgrades. The CLI + management API as first-class surfaces.

Why teams switch from Clerk

Clerk has excellent DX. The two most common reasons we see for switching:

  1. Pricing surprises at scale. Clerk's organizations + members billing model can compound — a single customer in 50 orgs counts 50 times. Authio bills per unique user.
  2. Wanting a deeper auth platform. Clerk is mostly the UI + the user store. Authio adds SCIM, custom-domain hosted UI, the risk engine, fine-grained authorization (FGA), and the full audit stream.

Sessions

Clerk sessions are dropped on cutover. Users sign in via passkey, magic-link, or OAuth on next visit. Their external account identities are preserved, so the “Sign in with Google” flow re-authenticates the same Google account they already used.

Rollback plan

Run both in parallel during a phased cutover. Re-run the importer nightly. Clerk and Authio share enough of the data model that re-running is fast.

Step-by-step: CLI

# 1) Generate a Backend API secret key in the Clerk dashboard.

# 2) Page through /v1/users and concatenate the data arrays.
curl 'https://api.clerk.com/v1/users?limit=500' \
  -H "Authorization: Bearer $CLERK_SECRET_KEY" \
  > clerk.json
# (Repeat with ?offset=500, 1000, ... and concat the .data arrays.)

# 3) Dry-run.
authio import clerk --input ./clerk.json --dry-run | jq '.stats'

# 4) Apply.
authio import clerk --input ./clerk.json

Step-by-step: dashboard wizard

Visit app.authio.com/migrate/clerk.

Live import (paste an API token)

The fastest path: paste your Clerk Secret Key into the dashboard wizard and Authio pulls everything (users, orgs, memberships) live from api.clerk.com.

  1. In Clerk dashboard → API Keys → copy the Secret Key (starts with sk_live_).
  2. In Authio: Migrate from Clerk → Connect with API token. Paste the secret. The wizard validates it against GET /v1/users?limit=1.
  3. Click Start import — progress is polled every 2s.
Tokens are encrypted at rest with envelope encryption and the credential row is auto-deleted within 24 hours.

Live import via the CLI

authio import clerk \
  --live-token "$CLERK_SECRET_KEY" \
  --dry-run

Post-migration checklist

  • Swap @clerk/nextjs for @authio/nextjs. The session-cookie reading API is similar.
  • Replace SignIn / UserButton components with Authio's hosted UI or React SDK.
  • Re-create webhooks (Clerk's svix-style webhook subscribers map onto Authio webhooks).
  • Send migration emails.
Clerk's organization invitations don't map directly. After migration, recreate any pending invitations via POST /v1/organizations/:orgId/invitations.