Expo Native Components, Beta
The Clerk Expo SDK provides prebuilt native UI components rendered with SwiftUI on iOS and Jetpack Compose on Android. These components provide a fully native authentication experience for Expo apps.
<AuthView /> and <UserProfileView /> render inline in your React Native view hierarchy, so you can place them in a modal, route, full-screen view, or any other layout that fits your app. <UserButton /> renders the platform-native Clerk button and opens <UserProfileView /> when tapped.
Available components
Requirements
Native components require:
-
Expo SDK 54 or later. See the quickstart guide.
-
A development build (
npx expo run:iosornpx expo run:android), as these components are not available in Expo Go. -
The
@clerk/expo-native-componentspackage and its config plugin. See Installation. -
If using social connections, you must register your native application credentials in the Clerk Dashboard. See the Sign in with Google and Sign in with Apple guides for setup steps.
Installation
Native components require @clerk/expo-native-components, a separate package from @clerk/expo.
npx expo install @clerk/expo-native-componentsAdd the config plugin
Then add its config plugin to your app config, alongside @clerk/expo. See the available plugin options.
{
"expo": {
"plugins": ["@clerk/expo", "@clerk/expo-native-components"]
}
}Import the components
Rebuild your development build to include the native code. Then, import the components from @clerk/expo/native-components:
import { AuthView, UserButton, UserProfileView } from '@clerk/expo/native-components'- Name
keychainService- Type
string- Description
Custom keychain service identifier. Required if you need extension targets (widgets, App Clips, Watch) to share the keychain with the main app.
- Name
theme- Type
string- Description
Path to a JSON file that customizes the appearance of the native components on iOS and Android (colors, dark mode, border radius, and font family). See the Theming reference for platform-specific details and the full schema.
- Name
appleSignIn- Type
boolean- Description
Whether to add the
com.apple.developer.applesigninentitlement. Set tofalseif your app does not use Apple Sign In. Defaults totrue.
- Name
faceIDPermission- Type
string- Description
The Face ID usage description that the plugin adds to your app's
Info.plistasNSFaceIDUsageDescription. Required to support Face ID for biometric sign-in.
{
"expo": {
"plugins": [
["@clerk/expo", { "appleSignIn": false }],
["@clerk/expo-native-components", { "keychainService": "com.example.myapp" }]
]
}
}Respond to auth changes
Use hooks like useAuth(), useUser(), or useSession() to read authentication state and update your UI after auth changes.
The following example demonstrates one way to open <AuthView /> from a sign-in button.
import { AuthView } from '@clerk/expo/native-components'
import { useAuth, useUser } from '@clerk/expo'
import { useState } from 'react'
import { Button, Modal, Text, View } from 'react-native'
export default function HomeScreen() {
const { isSignedIn } = useAuth({ treatPendingAsSignedOut: false })
const { user } = useUser()
const [isAuthOpen, setIsAuthOpen] = useState(false)
return (
<View>
{isSignedIn ? (
<Text>User ID: {user?.id}</Text>
) : (
<Button title="Sign in" onPress={() => setIsAuthOpen(true)} />
)}
<Modal
animationType="slide"
visible={isAuthOpen}
presentationStyle="pageSheet"
onRequestClose={() => setIsAuthOpen(false)}
>
<AuthView onDismiss={() => setIsAuthOpen(false)} />
</Modal>
</View>
)
}When rendering <AuthView /> or <UserProfileView /> directly in a route or full-screen view, pass isDismissible={false} if users must complete the flow to continue.
<AuthView isDismissible={false} /><UserProfileView isDismissible={false} style={{ flex: 1 }} />Web compatibility
For Expo web projects, use the web-specific components from @clerk/expo/web. Expo Router requires a non-platform route alongside a platform-specific route, so this example includes both files:
src/
└── app/
├── sign-in.tsx
└── sign-in.web.tsximport { AuthView } from '@clerk/expo/native-components'
export default function Page() {
return <AuthView isDismissible={false} />
}import { SignIn } from '@clerk/expo/web'
export default function Page() {
return <SignIn />
}<AuthView /> doesn't navigate on its own — see the full-screen example for redirecting once authentication completes. See the web component reference for more information.
Feedback
Last updated on