All skills
clerk avatar

/clerk-expo

@3d0c898 official
by clerkclerk/skills83 stars
5

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.

Use this Skill: https://skilld.dev/gh/clerk/skills/clerk-expo

This session only. Nothing lands on disk.

referencesrecipes.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Recipes: users, orgs, sign-out, backend calls, device features

Post-auth patterns. Hooks below are imported from @clerk/expo unless noted; they mirror @clerk/react.

Canonical docs (fetch to re-verify if the installed SDK is newer than 3.6.x): https://clerk.com/docs/reference/expo/overview — plus local-credentials and passkeys pages under the Expo reference

User profile data

import { useUser } from '@clerk/expo'

const { user, isLoaded } = useUser()
// user is null until loaded/signed in — always guard
// user.fullName, user.firstName, user.imageUrl, user.primaryEmailAddress?.emailAddress

For a full profile management UI on a dev build, prefer the native UserProfileView / UserButton (prebuilt-components.md) over hand-built screens.

Sign out

import { useClerk } from '@clerk/expo'

const { signOut } = useClerk()
<Pressable onPress={() => signOut()}>...</Pressable>

Organization switching (B2B)

Organizations must be enabled in the dashboard. For deeper org work (roles, invitations, RBAC) load the clerk-orgs skill — the hooks are identical in Expo.

import { useOrganization, useOrganizationList } from '@clerk/expo'

const { organization } = useOrganization()
const { setActive, userMemberships } = useOrganizationList({
  userMemberships: { infinite: true },
})

// Current: organization?.name ?? 'Personal account'
// Switch: setActive({ organization: membership.organization.id })
// List: userMemberships.data?.map((m) => m.organization) — guard while undefined

Calling your backend

Route guards are client-side only; authorize on the server:

import { useAuth } from '@clerk/expo'

const { getToken } = useAuth()
const res = await fetch(`${API_URL}/endpoint`, {
  headers: { Authorization: `Bearer ${await getToken()}` },
})

Verify the token server-side with Clerk's backend SDK for your server framework (e.g. @clerk/backend's verifyToken, or the framework SDK's getAuth). Clerk has no official Expo Router API-routes (+api.ts) integration — treat any server code as a normal backend and use @clerk/backend.

Push notifications with user context

Associate the Expo push token with the Clerk user:

import { useUser } from '@clerk/expo'
import * as Notifications from 'expo-notifications'
import { useEffect } from 'react'

export function PushTokenRegistrar() {
  const { user, isLoaded } = useUser()

  useEffect(() => {
    if (!isLoaded || !user) return
    ;(async () => {
      const { status } = await Notifications.requestPermissionsAsync()
      if (status !== 'granted') return
      const token = (await Notifications.getExpoPushTokenAsync()).data
      await user.update({
        unsafeMetadata: { ...user.unsafeMetadata, expoPushToken: token },
      })
    })()
  }, [isLoaded, user])

  return null
}
  • unsafeMetadata is client-writable; anything that must be trusted belongs in publicMetadata, written server-side via the Backend SDK.
  • Server send: look up the user with the Backend SDK, read unsafeMetadata.expoPushToken, POST to https://exp.host/--/api/v2/push/send.
  • Re-register after sign-out/sign-in as a different user.

Biometric re-auth — useLocalCredentials()

Dev build only. Stores the user's credentials in the keychain, gated by Face ID / Touch ID / device biometrics, for fast re-sign-in.

Prerequisites: npx expo install expo-local-authentication (plus expo-secure-store from setup), iOS NSFaceIDUsageDescription in app.json → ios.infoPlist.

import { useLocalCredentials } from '@clerk/expo/local-credentials'

const { hasCredentials, setCredentials, authenticate, biometricType } = useLocalCredentials()

// After a successful password sign-in, offer to enable biometrics:
await setCredentials({ identifier: emailAddress, password })

// On later launches, if hasCredentials:
const signInResource = await authenticate() // prompts biometrics, performs the sign-in

Password-based instances only — it replays stored credentials. Confirm the exact return shape against node_modules/@clerk/expo/dist/local-credentials/*.d.ts before wiring UI.

Passkeys

Dev build only. Install the separate @clerk/expo-passkeys package, then import from the @clerk/expo/passkeys subpath — the subpath re-exports the peer package (this install/import pairing is intentional and matches the docs). Pass it to the provider and enable passkeys in the dashboard:

import { passkeys } from '@clerk/expo/passkeys'

<ClerkProvider publishableKey={publishableKey} tokenCache={tokenCache} __experimental_passkeys={passkeys}>

Requires associated-domains setup (iOS) / asset links (Android). Fetch https://clerk.com/docs/reference/expo/passkeys for the current platform configuration before implementing — this surface is still experimental and changes.

Offline resource caching

If Clerk resources (user, session) should survive offline cold starts, pass resourceCache from @clerk/expo/resource-cache to the provider (__experimental_resourceCache). @clerk/expo/secure-store is the deprecated alias — never use it in new code.

Source: SKILL.md on GitHub

No alerts16d3 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The analyzed skill defines safe, verified integration patterns for the @clerk/expo authentication library in Expo and React Native applications. It appropriately specifies standard secret management guidelines (storing publishable keys in environment files rather than hardcoding them) and does not exhibit any malicious behaviors such as data exfiltration, prompt injection, or obfuscation.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

Signed by skilld at 3d0c898. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 3 months ago
What it can do
Network
metadata
{
  "author": "clerk",
  "version": "2.0.0"
}
All 1 allowed tools
WebFetch
Other metadata
compatibility
Requires @clerk/expo v3.4+ (written against v3.6.x, July 2026). Expo SDK 53-56, React Native 0.75+.

README badge

README badge for clerk/skills/clerk-expo

Implements Clerk authentication in Expo and React Native projects using @clerk/expo, supporting either prebuilt AuthView/UserButton components or custom hook-driven flows. Handles ClerkProvider setup, token persistence, native sign-in strategies, and Expo config plugin registration—excludes native iOS/Swift, native Android/Kotlin, and web-only frameworks.

Generated from the current SKILL.md.

Does this skill work with native iOS/Swift or native Android/Kotlin projects?
No. This skill is for Expo and React Native only. Native iOS/Swift and native Android/Kotlin projects should use their respective Clerk SDKs, not this skill.
Do I need a development build or can I use Expo Go?
Native components like AuthView and UserButton require an iOS/Android development build. Expo Go does not support native modules. For web targets, use the @clerk/expo/web exports instead.
What's the difference between prebuilt and custom flows?
Prebuilt uses Clerk's AuthView or UserButton components for the fastest setup. Custom hook-driven flows give you full control over the UI and authentication state but require more implementation work.
Do I need to set the publishable key via environment variables?
No. Pass the publishable key directly to <ClerkProvider publishableKey={key}> unless you explicitly ask for environment-variable indirection. The skill will not introduce env-var wiring by default.
Does this skill cover Expo-specific recipes like token caching and protected routes?
This skill covers flow selection and end-to-end setup. Expo-specific recipes (SecureStore token cache, OAuth deep-link configuration, Expo Router protected routes) are in the clerk-expo-patterns skill instead.

Generated from the current SKILL.md. These answers refresh after source changes.