Add Clerk authentication to Expo and React Native apps using @clerk/expo. Use for Expo setup, prebuilt native components (AuthView, UserButton), custom sign-in/sign-up flows (email, password, SMS/phone OTP, MFA), OAuth/SSO, native Google/Apple sign-in, Expo Router protected routes, biometrics, and push notifications. Do not use for native Swift/iOS, native Android/Kotlin, or web-only framework projects.
Installation
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Add Clerk authentication to Expo and React Native apps using @clerk/expo. Use for Expo setup, prebuilt native components (AuthView, UserButton), custom sign-in/sign-up flows (email, password, SMS/phone OTP, MFA), OAuth/SSO, native Google/Apple sign-in, Expo Router protected routes, biometrics, and push notifications. Do not use for native Swift/iOS, native Android/Kotlin, or web-only framework projects.
license
MIT
allowed-tools
WebFetch
metadata
{"author":"clerk","version":"2.0.0"}
compatibility
Requires @clerk/expo v3.4+ (written against v3.6.x, July 2026). Expo SDK 53-56, React Native 0.75+.
Clerk Expo (React Native)
Implement Clerk in Expo / React Native projects. This skill inlines verified patterns for the stable surface (provider, token cache, flows) and requires source inspection of the installed @clerk/expo package for anything volatile (component props, hook signatures).
Activation Rules
Activate when either is true:
The user asks for auth in an Expo or React Native app, or mentions @clerk/expo, ClerkProvider, Expo Router auth, or Clerk hooks in a native app.
The project is Expo/React Native (app.json / app.config.js, expo in package.json, metro.config.js, @clerk/expo dependency).
"Protect routes/screens", "redirect if signed out"
Expo Router guards
references/protected-routes.md
"Show user profile", "org switching", "push notifications", "sign out", "call my backend"
App recipes
references/recipes.md
"Biometric login", "Face ID", "passkeys"
Device features
references/recipes.md
Default Path Decision
When the user says "add auth" without specifying UI:
Default to prebuilt native components (AuthView + UserButton from @clerk/expo/native). Fastest to working auth; UI is maintained by Clerk. Tell the developer they are in beta and require a development build.
Fall back to custom flows when any of these hold — say why when you switch:
The project must run in Expo Go (no dev build).
The app targets web (native components don't render on web).
The developer wants their own UI or a specific brand experience beyond theming.
If the developer has an existing auth UI, extend what's there — don't rip out custom flows to insert AuthView (or vice versa) without being asked.
Do not blend prebuilt components and custom flows for the same auth step (e.g. AuthView plus a custom password form). Blending is allowed only when the developer explicitly asks.
Quick Workflow
Confirm project type (Expo/RN) and pick the path per the Intent Map / Default Path rules.
Verify dashboard prerequisites (Gate 2 and Gate 3 below).
Implement from the selected reference only.
Verify by building, not just by writing:
Run the project's typecheck (npx tsc --noEmit or equivalent).
Build and launch: npx expo run:ios / run:android for native features, npx expo start for Expo Go flows. If the build fails, fix and rebuild iteratively — build errors against the installed SDK are the ground truth when this skill and the SDK disagree. After ~5 failed fix attempts, stop and ask the developer how to proceed instead of thrashing.
Walk the developer through one real sign-in, then confirm the session survives an app restart (token cache working).
Execution Gates (Do Not Skip)
Publishable key — Read from process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY (.env file). Never NEXT_PUBLIC_, never hardcoded. If no key exists, ask the developer for one (or run npx clerk@latest init --framework expo, which installs the SDK and writes the env file) and wait before editing files.
Native API dashboard toggle — Clerk's Native API must be enabled for the instance: Clerk Dashboard → Native applications (https://dashboard.clerk.com/~/native-applications). Tell the developer to verify this during setup; it is required for any native integration.
Factor availability — Before implementing a specific strategy (SMS, email code, social provider), confirm it's enabled for the instance. Derive the Frontend API URL from the publishable key (base64-decode the middle segment) and fetch <frontendApiUrl>/v1/environment?_is_native=true, or ask the developer to check the dashboard (User & authentication). SMS in particular is instance-configuration-dependent — code written for a disabled factor fails at runtime, not build time.
Current custom-flows API only — useSignIn() / useSignUp() from @clerk/expo (v3.4+) return { signIn, errors, fetchStatus } and use method-based flows: signIn.password(), signIn.phoneCode.sendCode(), signIn.finalize(). Never generate the legacy pattern: destructuring isLoaded/setActive from useSignIn()/useSignUp() (the current hooks don't return them), or signIn.create() chained with prepareFirstFactor()/attemptFirstFactor() + setActive({ session }). That pattern lives at @clerk/expo/legacy and is only for maintaining existing legacy code, never for new work. Scope notes: isLoaded from useAuth()/useUser() is current API and required in guards; signIn.create() itself still exists for advanced cases — prefer the factor-specific methods.
useSSO(), never useOAuth() — useOAuth is deprecated. Note the asymmetry: startSSOFlow() still returns { createdSessionId, setActive } and requires setActive({ session: createdSessionId }) — SSO does not use finalize().
Token cache — tokenCache from @clerk/expo/token-cache on ClerkProvider. Never use expo-secure-store directly for session tokens, never AsyncStorage.
resourceCache, never secureStore — if offline resource caching comes up, @clerk/expo/secure-store is deprecated; use resourceCache from @clerk/expo/resource-cache.
Build-type gating — Native components (@clerk/expo/native) and native hooks (useSignInWithGoogle, useSignInWithApple, useLocalCredentials) require a development build (npx expo run:ios / run:android), not Expo Go, and don't exist on web. For web targets use @clerk/expo/web components or custom flows. State the build requirement before implementing a native-only feature.
Combined sign-in-or-up default — one combined flow unless the developer asks for separate sign-in and sign-up screens.
Bot protection — custom sign-up screens must render <View nativeID="clerk-captcha" />; Clerk's bot protection is on by default and needs this mount point.
Source verification for volatile surfaces — before using native component props or native hook options, confirm against the installed package: node_modules/@clerk/expo/dist/native/*.d.ts and package.jsonexports. The installed version wins over this skill if they disagree.
Freshness gate — this skill was verified against @clerk/expo 3.6.x. Check the installed version (node_modules/@clerk/expo/package.json). If it is a newer minor or major, treat this skill's code snippets as suspect: re-verify against the docs URL cited next to each snippet (every reference section carries one) or the installed .d.ts before using them. If it is older than 3.4, the method-based custom-flows API may not exist — offer an upgrade instead of writing legacy code.
Version Notes (v3.5–v3.6, June 2026)
Minimum React Native raised to 0.75 in v3.5.0 (iOS SDK now links via SPM podspec). Peer range: expo >=53 <57.
Native components matured: iOS moved to Expo Modules; native↔JS session sync is automatic and bidirectional — never call setActive() after native-component auth.
The config plugin accepts a theme JSON file for native component styling (see references/prebuilt-components.md).
Native Google sign-in will move to a separate @clerk/expo-google-signin package in the next major (the @clerk/expo/google import keeps working in v3; a dev warning announces the migration). Don't preinstall the new package on v3.