kavachOS

Expo / React Native

KavachOS auth for React Native and Expo apps.

@kavachos/expo brings KavachOS auth to React Native and Expo apps. It stores session tokens in any storage adapter you choose — AsyncStorage, SecureStore, or your own — and sends them via Authorization header rather than cookies.

Installation

npm install @kavachos/expo
# or
pnpm add @kavachos/expo

You also need a storage library. The most common choices:

npx expo install @react-native-async-storage/async-storage
# or for encrypted storage
npx expo install expo-secure-store

Setup

Wrap your app

// app/_layout.tsx (Expo Router) or App.tsx
import { KavachExpoProvider } from '@kavachos/expo';
import AsyncStorage from '@react-native-async-storage/async-storage';

export default function RootLayout() {
  return (
    <KavachExpoProvider
      config={{
        basePath: 'https://api.myapp.com/api/kavach',
        storage: AsyncStorage,
      }}
    >
      <Stack />
    </KavachExpoProvider>
  );
}

The storage prop accepts any object with getItem, setItem, and removeItem methods — the same interface as AsyncStorage and expo-secure-store.

Use the hooks

import { useSignIn, useUser } from '@kavachos/expo';

export function LoginScreen() {
  const { signIn, isLoading, error } = useSignIn();

  async function handleLogin() {
    const result = await signIn('user@example.com', 'password');
    if (result.success) {
      router.replace('/home');
    }
  }

  return (
    <View>
      <Button onPress={handleLogin} disabled={isLoading} title="Sign in" />
      {error && <Text>{error}</Text>}
    </View>
  );
}

Secure token storage

For production apps, use expo-secure-store to encrypt the session token at rest:

import * as SecureStore from 'expo-secure-store';
import { KavachExpoProvider } from '@kavachos/expo';

const secureStorage = {
  getItem: (key: string) => SecureStore.getItemAsync(key),
  setItem: (key: string, value: string) => SecureStore.setItemAsync(key, value),
  removeItem: (key: string) => SecureStore.deleteItemAsync(key),
};

<KavachExpoProvider config={{ basePath: '...', storage: secureStorage }}>
  {children}
</KavachExpoProvider>

For OAuth flows in Expo, use the oauth-proxy plugin on your server alongside Linking.openURL on the client:

import { Linking } from 'react-native';

async function signInWithGitHub() {
  const authUrl = 'https://api.myapp.com/api/kavach/auth/oauth/github/authorize';
  await Linking.openURL(authUrl);
  // Handle the redirect via Linking.addEventListener or expo-linking
}

Hooks reference

useSession

const { session, isLoading, refresh } = useSession();

useUser

const { user, isLoading, isAuthenticated } = useUser();

useSignIn

const { signIn, isLoading, error } = useSignIn();
const result = await signIn(email, password);

useSignUp

const { signUp, isLoading, error } = useSignUp();
const result = await signUp(email, password, name);

useSignOut

const { signOut } = useSignOut();
await signOut(); // clears stored token and calls server sign-out

useAgents

const { agents, create, revoke, rotate, isLoading, error } = useAgents(basePath);

Manages agent identity records for the current user. Requires the full base URL (same as the provider config).

KavachExpoConfig

FieldTypeDescription
basePathstringFull URL to your KavachOS mount point
storageKavachStorage?Token persistence adapter. Defaults to in-memory

The default in-memory storage loses the session when the app restarts. Always pass a real storage adapter in production.

On this page