YouVersion PlatformYouVersion Platform
PlatformBiblesDev Docs
CommunityPartnersSupport

YouVersion Platform

Build applications and integrate with the world's most popular Bible platform.

Platform Products

  • Platform Portal
  • Developer Documentation
  • App Management

Resources

  • Support
  • Press inquiries

Legal

  • Privacy Policy
  • Terms of Use

© 2026 YouVersion. All rights reserved.

  • Overview
  • API Reference
  • SDKs
  • Changelog
<  Back to Platform
SDK IntroductionSwift SDKKotlin SDK
JavaScript SDK
React SDK
React Native (Expo) SDK
    Quick StartComponentsAuthentication
    Guides
React Native (Expo) SDK

Authentication

Authentication is optional. When enabled, the SDK signs users in with YouVersion using the PKCE OAuth flow, stores tokens securely in expo-secure-store, caches the user's profile, and refreshes tokens automatically.

The YouVersionProvider, YouVersionAuthButton, and the useYVAuth hook power the flow:

  • YouVersionProvider — pass an auth config to enable authentication.
  • YouVersionAuthButton — pre-styled sign-in/sign-out button from @youversion/platform-react-native-expo-ui.
  • useYVAuth — imported from @youversion/platform-react-native-expo-core to read auth state and trigger sign-in/sign-out when you build a custom UI.

Use YouVersionAuthButton for a drop-in button, or useYVAuth when you need full control over the sign-in experience.


Setup

  1. Add a URL scheme to your app

    The OAuth redirect comes back to your app via a deep link. Register a custom URL scheme in app.json — this becomes the prefix for your redirect URI (e.g. scheme com.example.myapp → redirect com.example.myapp://callback).

    Pick a unique value, typically a reverse-DNS identifier for your app. It must contain only lowercase letters, numbers, dots, and hyphens. Custom URL schemes have no ownership registry on either platform: on Android, if two installed apps claim the same scheme the OS shows a disambiguation dialog asking the user which app to open, and on iOS there is no defined process for which app wins a duplicated scheme — so choose a scheme unique to your app:

    app.json
    { "expo": { "scheme": "com.example.myapp" } }
  2. Register your redirect URI

    Your redirect URI is the value from step 1 — your scheme plus ://callback (e.g. com.example.myapp://callback). Add it as a Callback URI in your app's settings in the YouVersion Platform console.

    In code, expo-linking builds the same URI for you — install it with npx expo install expo-linking:

    Code
    import * as Linking from "expo-linking"; const redirectUri = Linking.createURL("callback"); // e.g. com.example.myapp://callback

    The redirectUri you pass to the provider must match a Callback URI registered in your YouVersion Platform app settings, or sign-in will fail.

  3. Enable auth on the provider

    Pass the auth config to YouVersionProvider:

    app/_layout.tsx
    import { YouVersionProvider } from "@youversion/platform-react-native-expo-ui"; import * as Linking from "expo-linking"; import { Stack } from "expo-router"; import { GestureHandlerRootView } from "react-native-gesture-handler"; export default function RootLayout() { const appKey = process.env.EXPO_PUBLIC_YOUVERSION_APP_KEY; const redirectUri = Linking.createURL("callback"); if (!appKey) return null; return ( <GestureHandlerRootView style={{ flex: 1 }}> <YouVersionProvider appKey={appKey} auth={{ redirectUri, scopes: ["profile", "email"] }} > <Stack screenOptions={{ headerShown: false }} /> </YouVersionProvider> </GestureHandlerRootView> ); }

    Scopes: request "profile" and "email" to read the user's name, email, and avatar. Without them, those fields on userInfo will be undefined. Scopes default to ["profile", "email"].

  4. Add the callback route

    Create a route that matches the path in your redirectUri (here, callback). The SDK completes the token exchange inside the in-app browser session, so the route only needs to return the user to your app:

    app/callback.tsx
    import { useRouter } from "expo-router"; import { useEffect } from "react"; export default function AuthCallback() { const router = useRouter(); useEffect(() => { if (router.canGoBack()) { router.back(); } else { router.replace("/"); } }, [router]); return null; }
  5. Add Sign in with YouVersion (Optional)

    Drop in the pre-styled button anywhere under the provider. It handles sign-in and sign-out for you:

    app/(tabs)/profile.tsx
    import { YouVersionAuthButton } from "@youversion/platform-react-native-expo-ui"; import { useColorScheme, View } from "react-native"; export default function ProfileScreen() { const isDark = useColorScheme() === "dark"; return ( <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}> <YouVersionAuthButton mode="auto" background={isDark ? "dark" : "light"} outline /> </View> ); }

    See YouVersionAuthButton for styling props.

  6. Use our Authentication hook (Optional)

    When you need a custom sign-in UI, call signIn() and signOut() from useYVAuth directly:

    SignInButton.tsx
    import { useYVAuth } from "@youversion/platform-react-native-expo-core"; import { Button, Text } from "react-native"; export function SignInButton() { const { isAuthenticated, isLoading, userInfo, signIn, signOut } = useYVAuth(); if (isLoading) return null; if (isAuthenticated) { return ( <> <Text>Welcome, {userInfo?.name}!</Text> <Button title="Sign out" onPress={() => signOut()} /> </> ); } return <Button title="Sign in with YouVersion" onPress={() => signIn()} />; }

useYVAuth

useYVAuth returns the current authentication state and actions. It must be used under a YouVersionProvider that has the auth prop set, otherwise it throws.

Code
import { useYVAuth } from "@youversion/platform-react-native-expo-core"; const { isAuthenticated, userInfo, signIn, signOut } = useYVAuth();

Return value:

FieldTypeDescription
isAuthenticatedbooleantrue when a valid access token is present.
isLoadingbooleantrue while tokens are being loaded or restored on startup.
userInfoYVUserInfo | nullThe signed-in user's profile, or null.
accessTokenstring | nullCurrent access token, for calling the Platform API on the user's behalf.
errorError | nullThe most recent auth error, if any.
signIn() => Promise<void>Starts the PKCE sign-in flow in an in-app browser.
signOut() => Promise<void>Clears stored tokens and signs the user out.
refreshNow() => Promise<void>Forces a token refresh. Tokens also refresh automatically.

YVUserInfo:

Code
type YVUserInfo = { id?: string; name?: string; email?: string; avatarUrl?: string; // resolved URL };

Token handling. Access and refresh tokens are stored in expo-secure-store; profile metadata is cached in MMKV. Tokens refresh automatically when they near expiry and when the app returns to the foreground — you don't need to manage this yourself.


Sample app

The apps/example directory contains a working Expo Router app with the provider setup, the callback route, and an auth debug screen.

Last modified on July 20, 2026
ComponentsCopyright & Attribution
On this page
  • Setup
  • useYVAuth
  • Sample app
JSON
React
React
React
React
React
React
TypeScript