
Security News
White House Authorizes Private Companies to Conduct Offensive Cyber Operations
A new federal program will let vetted U.S. cybersecurity firms help investigate and disrupt foreign cybercrime groups under government direction.
@authon/react-native
Advanced tools
English | 한국어
React Native SDK for Authon authentication. Provides React hooks, social login with in-app browser, and secure token storage.
npm install @authon/react-native @authon/js
Peer dependencies:
npm install react-native react-native-svg
| Peer dependency | Version |
|---|---|
react | ^18.0.0 || ^19.0.0 |
react-native | >=0.70.0 |
react-native-svg | >=12.0.0 |
Wrap your app with AuthonProvider and pass a token storage adapter. For secure storage, use expo-secure-store (Expo) or react-native-keychain (bare RN).
// App.tsx
import React from 'react';
import { AuthonProvider } from '@authon/react-native';
import * as SecureStore from 'expo-secure-store';
const storage = {
getItem: (key: string) => SecureStore.getItemAsync(key),
setItem: (key: string, value: string) => SecureStore.setItemAsync(key, value),
removeItem: (key: string) => SecureStore.deleteItemAsync(key),
};
export default function App() {
return (
<AuthonProvider publishableKey="pk_live_..." storage={storage}>
<Navigation />
</AuthonProvider>
);
}
Without a storage adapter, tokens persist only in memory and are lost on app restart.
useAuthon()Returns the full auth context.
import { useAuthon } from '@authon/react-native';
const {
isLoaded, // boolean — true once the initial auth check is complete
isSignedIn, // boolean
userId, // string | null
sessionId, // string | null
accessToken, // string | null
user, // AuthonUser | null
signIn, // (params: SignInParams) => Promise<void>
signUp, // (params: SignUpParams) => Promise<void>
signOut, // () => Promise<void>
getToken, // () => string | null — returns current access token
providers, // OAuthProviderType[] — enabled providers from your project config
branding, // BrandingConfig | null
startOAuth, // (provider, redirectUri?) => Promise<{ url: string; state: string }>
completeOAuth, // (state: string) => Promise<void>
on, // (event, listener) => () => void — subscribe to auth events
client, // AuthonMobileClient — underlying client instance
} = useAuthon();
useUser()Convenience hook that returns only user state.
import { useUser } from '@authon/react-native';
const { isLoaded, isSignedIn, user } = useUser();
import React, { useState } from 'react';
import { View, TextInput, Button, Text, ActivityIndicator } from 'react-native';
import { useAuthon } from '@authon/react-native';
export function LoginScreen() {
const { signIn, isLoaded } = useAuthon();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleSignIn = async () => {
setLoading(true);
setError(null);
try {
await signIn({ strategy: 'email_password', email, password });
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
};
if (!isLoaded) return <ActivityIndicator />;
return (
<View style={{ padding: 24, gap: 12 }}>
<TextInput
placeholder="Email"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
/>
<TextInput
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
{error && <Text style={{ color: 'red' }}>{error}</Text>}
<Button title={loading ? 'Signing in...' : 'Sign In'} onPress={handleSignIn} disabled={loading} />
</View>
);
}
Use the built-in SocialButtons component. It fetches the enabled providers from your Authon project and renders buttons automatically.
import React from 'react';
import { View } from 'react-native';
import { SocialButtons } from '@authon/react-native';
export function SocialLoginSection() {
return (
<View style={{ padding: 24 }}>
<SocialButtons
onSuccess={() => console.log('Signed in')}
onError={(err) => console.error(err)}
/>
</View>
);
}
Compact icon-only layout:
<SocialButtons
compact
onSuccess={() => console.log('Signed in')}
onError={(err) => console.error(err)}
/>
Individual SocialButton:
import { SocialButton } from '@authon/react-native';
<SocialButton
provider="google"
onPress={(provider) => handleOAuth(provider)}
loading={isLoading}
label="Continue with Google" // optional — defaults to "Continue with Google"
compact={false} // optional — icon-only square button
height={48} // optional — button height in px
borderRadius={10} // optional
/>
SocialButtons handles OAuth automatically. For custom flows, use startOAuth and completeOAuth directly. OAuth uses the device browser (via Linking.openURL) rather than a popup.
import React, { useState } from 'react';
import { Button, Linking } from 'react-native';
import { useAuthon } from '@authon/react-native';
export function GoogleSignInButton() {
const { startOAuth, completeOAuth } = useAuthon();
const [loading, setLoading] = useState(false);
const handleGoogleSignIn = async () => {
setLoading(true);
try {
const { url, state } = await startOAuth('google');
// Open the OAuth URL in the default browser
await Linking.openURL(url);
// Poll for OAuth completion (3 minute timeout)
await completeOAuth(state);
} catch (err: any) {
if (err.message !== 'OAuth timeout') {
console.error('OAuth failed:', err);
}
} finally {
setLoading(false);
}
};
return (
<Button
title={loading ? 'Signing in...' : 'Sign in with Google'}
onPress={handleGoogleSignIn}
disabled={loading}
/>
);
}
import React, { useEffect, useState } from 'react';
import { View, Text, Button, FlatList } from 'react-native';
import { useAuthon } from '@authon/react-native';
export function SessionsScreen() {
const { client, userId, signOut } = useAuthon();
const [sessions, setSessions] = useState<any[]>([]);
useEffect(() => {
if (!userId) return;
// Access the underlying AuthonMobileClient for advanced operations
client.getUser().then(() => {
// sessions are managed server-side; use @authon/node on the backend
// to list and revoke sessions via authon.sessions.list(userId)
});
}, [userId]);
return (
<View>
<Button title="Sign Out (all devices)" onPress={signOut} />
</View>
);
}
MFA (TOTP) is configured on the client side through the underlying @authon/js client. Access it via client from useAuthon().
import React, { useState } from 'react';
import { View, TextInput, Button, Text, Image } from 'react-native';
import { useAuthon } from '@authon/react-native';
export function MfaSetupScreen() {
const { client } = useAuthon();
const [qrCodeUri, setQrCodeUri] = useState<string | null>(null);
const [backupCodes, setBackupCodes] = useState<string[]>([]);
const [code, setCode] = useState('');
const setupMfa = async () => {
// Use the underlying client's MFA methods (via @authon/js)
const jsClient = (client as any)._jsClient;
if (!jsClient) return;
const setup = await jsClient.setupMfa();
setQrCodeUri(setup.qrCodeUri);
setBackupCodes(setup.backupCodes);
};
const verifyMfa = async () => {
const jsClient = (client as any)._jsClient;
await jsClient.verifyMfaSetup(code);
};
return (
<View style={{ padding: 24, gap: 12 }}>
{qrCodeUri ? (
<>
<Image source={{ uri: qrCodeUri }} style={{ width: 200, height: 200 }} />
<Text>Backup codes: {backupCodes.join(', ')}</Text>
<TextInput
placeholder="Enter 6-digit code"
value={code}
onChangeText={setCode}
keyboardType="numeric"
/>
<Button title="Verify" onPress={verifyMfa} />
</>
) : (
<Button title="Enable MFA" onPress={setupMfa} />
)}
</View>
);
}
import React, { useState } from 'react';
import { Button, View, Text } from 'react-native';
import { useAuthon } from '@authon/react-native';
export function Web3ConnectScreen() {
const { client } = useAuthon();
const [walletAddress, setWalletAddress] = useState<string | null>(null);
const connectWallet = async () => {
// Request nonce from Authon API via the underlying client
const apiUrl = client.getApiUrl();
const token = client.getAccessToken();
// 1. Get a sign message from Authon
const nonceRes = await fetch(`${apiUrl}/v1/auth/web3/nonce`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...(token ? { Authorization: `Bearer ${token}` } : {}),
'x-api-key': 'pk_live_...',
},
body: JSON.stringify({ address: walletAddress, chain: 'evm' }),
});
const { message } = await nonceRes.json();
// 2. Sign with your wallet library (e.g. WalletConnect, ethers)
// const signature = await wallet.signMessage(message);
// 3. Verify and link wallet
// await fetch(`${apiUrl}/v1/auth/web3/verify`, { ... })
};
return (
<View style={{ padding: 24 }}>
<Button title="Connect Wallet" onPress={connectWallet} />
</View>
);
}
import { useEffect } from 'react';
import { useAuthon } from '@authon/react-native';
function App() {
const { on } = useAuthon();
useEffect(() => {
const unsubSignedIn = on('signedIn', (user) => {
console.log('User signed in:', user.id);
});
const unsubSignedOut = on('signedOut', () => {
console.log('User signed out');
});
const unsubRefreshed = on('tokenRefreshed', () => {
console.log('Token refreshed');
});
const unsubError = on('error', (err) => {
console.error('Auth error:', err);
});
return () => {
unsubSignedIn();
unsubSignedOut();
unsubRefreshed();
unsubError();
};
}, [on]);
return null;
}
Unlike web SDKs, @authon/react-native does not use popups. OAuth flows open the system browser via Linking.openURL. After the user authenticates, the SDK polls the Authon API to complete the session (up to 3 minutes). The SocialButtons component handles this polling automatically.
<AuthonProvider>| Prop | Type | Description |
|---|---|---|
publishableKey | string | Your Authon publishable key (pk_live_...) |
apiUrl | string | Optional — custom API base URL |
storage | TokenStorage | Optional — secure storage adapter for token persistence |
children | React.ReactNode | App content |
TokenStorage interfaceinterface TokenStorage {
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
removeItem(key: string): Promise<void>;
}
SignInParamsinterface SignInParams {
strategy: 'email_password' | 'oauth';
email?: string;
password?: string;
provider?: string;
}
SignUpParamsinterface SignUpParams {
email: string;
password: string;
displayName?: string;
}
AuthonMobileClient methods| Method | Returns | Description |
|---|---|---|
signIn(params) | Promise<{ tokens, user }> | Sign in with email/password or OAuth |
signUp(params) | Promise<{ tokens, user }> | Create account and sign in |
signOut() | Promise<void> | Sign out and clear local session |
getUser() | Promise<AuthonUser | null> | Fetch current user from API |
getCachedUser() | AuthonUser | null | Return locally cached user |
getAccessToken() | string | null | Return current access token |
isAuthenticated() | boolean | Check if token is valid and not expired |
refreshToken(token?) | Promise<TokenPair | null> | Refresh the access token |
getProviders() | Promise<OAuthProviderType[]> | Fetch enabled OAuth providers |
getBranding() | Promise<BrandingConfig | null> | Fetch project branding config |
getOAuthUrl(provider, redirectUri) | Promise<{ url, state }> | Get OAuth authorization URL |
completeOAuth(state) | Promise<{ tokens, user }> | Poll for OAuth completion |
getApiUrl() | string | Return configured API base URL |
on(event, listener) | () => void | Subscribe to auth events, returns unsubscribe function |
setStorage(storage) | void | Set token storage adapter |
initialize() | Promise<TokenPair | null> | Load tokens from storage on app start |
destroy() | void | Clear timers and event listeners |
FAQs
Authon React Native SDK — mobile authentication
The npm package @authon/react-native receives a total of 46 weekly downloads. As such, @authon/react-native popularity was classified as not popular.
We found that @authon/react-native demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
A new federal program will let vetted U.S. cybersecurity firms help investigate and disrupt foreign cybercrime groups under government direction.

Research
/Security News
The campaign amassed more than 75,000 installs by targeting Russian-speaking users seeking access to blocked services.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.