---
title: "@xid-kit/expo"
description: "Expo SecureStore and WebBrowser adapters for @xid-kit/react-native plus an Expo Router route guard hook."
locale: "en"
---

> Documentation Index
> Fetch the locale documentation index at: https://xid.dev/en/llms.txt
> Use this file to discover all available pages before exploring further.

# @xid-kit/expo

## Status

Package status is **Current package**. Expo SecureStore and WebBrowser adapters, XidProvider, and Expo Router route guard hook are implemented. A real IdP round-trip on production infrastructure is still pending manual verification.

All PKCE logic, token exchange, and session management live in [@xid-kit/react-native](/sdks/react-native); this package provides adapters and Expo Router integration only.

## Provider setup

Inject `createSecureStoreAdapter` and `createExpoWebBrowserAdapter` into `XidProvider`. No top-level Expo module import is needed; adapters accept module instances so CI typecheck stays clean without Expo peer deps installed.

```tsx
import * as SecureStore from 'expo-secure-store'
import * as WebBrowser from 'expo-web-browser'
import { XidProvider, createSecureStoreAdapter, createExpoWebBrowserAdapter } from '@xid-kit/expo'

const tokenCache = createSecureStoreAdapter({ secureStore: SecureStore })
const browser = createExpoWebBrowserAdapter({ webBrowser: WebBrowser })

export default function App() {
  return (
<XidProvider
  publishableKey="pk_live_..."
  issuer="https://xid.dev"
  clientId="your_client_id"
  redirectUri="myapp://auth/callback"
  tokenCache={tokenCache}
  browser={browser}
>
  <RootLayout />
</XidProvider>
  )
}
```

## Sign in and sign out

```tsx
import { useSignIn, useSignOut } from '@xid-kit/expo'
import { Button } from 'react-native'

function SignInScreen() {
  const { signIn, signInState } = useSignIn()
  return (
<Button
  title={signInState.status === 'pending' ? 'Signing in...' : 'Sign In'}
  onPress={() => void signIn()}
/>
  )
}

function SignOutScreen() {
  const { signOut } = useSignOut()
  return <Button title="Sign Out" onPress={() => void signOut()} />
}
```

## Expo Router route guard

Call `useProtectedRoute` in a layout component. It reads `isLoaded`/`isSignedIn` from `useAuth` and calls `replace` from Expo Router inside a `useEffect`.

```tsx
import { useProtectedRoute } from '@xid-kit/expo'
import { useRouter, usePathname } from 'expo-router'

export default function RootLayout() {
  const router = useRouter()
  const pathname = usePathname()

  useProtectedRoute({
signInRoute: '/sign-in',
protectedRoute: '/(app)',
pathname,
replace: router.replace,
  })

  return <Slot />
}
```

## SecureStore key namespacing

Use `keyPrefix` to namespace keys under a custom prefix. The separator is `.` (dot), which is within the allowed character set for `expo-secure-store`.

```ts
const tokenCache = createSecureStoreAdapter({
  secureStore: SecureStore,
  keyPrefix: 'myapp',
  // keys: 'myapp.xid.access_token', 'myapp.xid.refresh_token', etc.
})
```

## Exported API

| Export | Kind | Purpose |
| --- | --- | --- |
| `XidProvider` | component | Re-export of @xid-kit/react-native XidProvider accepting tokenCache and browser adapters |
| `createSecureStoreAdapter` | function | TokenCache adapter backed by expo-secure-store; accepts secureStore instance and optional keyPrefix |
| `createExpoWebBrowserAdapter` | function | BrowserInterface adapter backed by expo-web-browser |
| `useSignIn` | hook | Re-export from @xid-kit/react-native: signIn, handleRedirect, signInState |
| `useSignOut` | hook | Re-export from @xid-kit/react-native: signOut, signOutState |
| `useProtectedRoute` | hook | Reads isLoaded/isSignedIn and calls Expo Router replace for route protection |

## Known limitations

- `useAuth().isSignedIn` reflects the `XidClient` web-cookie session state, which does not auto-populate from the local SecureStore tokens after token exchange. Reload client state explicitly after a successful sign-in.
- This package provides only adapters and Expo Router integration. For the base React Native PKCE flow, see [@xid-kit/react-native](/sdks/react-native).

Source: https://xid.dev/sdks/expo/index.mdx
