@loonylabs/react-native-offline-auth
v1.0.1
Published
Offline-first authentication library for React Native with Guest Mode and JWT support
Downloads
5
Maintainers
Readme
@loonylabs/react-native-offline-auth
Offline-first authentication library for React Native with Guest Mode and JWT support
A production-ready authentication library for React Native that prioritizes offline-first functionality. Built with TypeScript, Zustand, and AsyncStorage.
Features
- Offline-First - Works without internet, syncs when available
- Guest Mode - Let users try your app without registration
- Easy Upgrade - Seamless guest → authenticated account flow
- JWT Support - Standard JWT token management
- Type-Safe - Full TypeScript support with comprehensive types
- Zero Native Code - Pure JavaScript/TypeScript, works with Expo
- Flexible API - Bring your own API implementation
- Tree-Shakeable - Optimized bundle size
Installation
npm install @loonylabs/react-native-offline-auth zustand @react-native-async-storage/async-storageor
yarn add @loonylabs/react-native-offline-auth zustand @react-native-async-storage/async-storagePeer Dependencies
This library requires:
react>= 18.0.0react-native>= 0.70.0zustand>= 4.0.0@react-native-async-storage/async-storage>= 1.17.0
Quick Start
1. Wrap your app with AuthProvider
import { AuthProvider } from '@loonylabs/react-native-offline-auth';
import App from './App';
export default function Root() {
return (
<AuthProvider
apiCallbacks={{
login: async (credentials) => {
const response = await fetch('https://api.example.com/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credentials),
});
return response.json(); // { user, token }
},
register: async (credentials) => {
const response = await fetch('https://api.example.com/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credentials),
});
return response.json(); // { user, token }
},
validateToken: async (token) => {
const response = await fetch('https://api.example.com/auth/me', {
headers: { Authorization: `Bearer ${token}` },
});
const data = await response.json();
return data.user;
},
}}
>
<App />
</AuthProvider>
);
}2. Use the hook in your components
import { useAuth } from '@loonylabs/react-native-offline-auth';
function HomeScreen() {
const {
user,
isAuthenticated,
isGuestMode,
login,
logout,
continueAsGuest,
} = useAuth();
if (isGuestMode) {
return <Text>Welcome Guest! 👤</Text>;
}
if (isAuthenticated) {
return (
<View>
<Text>Welcome {user.username}! 🔐</Text>
<Button title="Logout" onPress={logout} />
</View>
);
}
return (
<View>
<Button title="Login" onPress={() => login({ email, password })} />
<Button title="Continue as Guest" onPress={continueAsGuest} />
</View>
);
}Core Concepts
Three Authentication States
- Authenticated - User logged in with JWT token
- Guest Mode - User using app without account (local data only)
- Unauthenticated - User needs to login or continue as guest
Offline-First Philosophy
- App starts immediately with cached credentials
- Token validation happens in background (non-blocking)
- Users stay logged in even when offline
- No forced logout on network errors
Navigation Logic
function RootNavigator() {
const { isLoading, isAuthenticated, isGuestMode } = useAuth();
if (isLoading) {
return <SplashScreen />;
}
if (isAuthenticated || isGuestMode) {
return <MainApp />;
}
return <AuthScreens />;
}Documentation
- Getting Started - Step-by-step setup guide
- API Reference - Complete API documentation
- Error Handling - Error handling guide
- Examples - Common use cases and patterns
- Example App - Full working example
Key Features Explained
Guest Mode
Allow users to try your app without registration:
await continueAsGuest();
// User can now use the app with local-only dataUpgrade to Account
Convert guest users to authenticated users:
await upgradeToAccount({
email: '[email protected]',
username: 'newuser',
password: 'securepass123'
});
// Local data is preserved, now synced to cloudOffline Authentication
Users stay logged in when offline:
// On app start:
// 1. Load token + user from AsyncStorage (instant)
// 2. Show app immediately
// 3. Validate token in background (when online)
// 4. Update user data if validation succeeds
// 5. Stay logged in even if validation fails (offline)Configuration
<AuthProvider
apiCallbacks={...}
config={{
// Custom storage keys (optional)
storageKeys: {
token: '@custom_token',
user: '@custom_user',
guestMode: '@custom_guest',
},
// Enable debug logging
debug: true,
// Custom token validator
validateToken: async (token) => {
// Your custom validation logic
return user;
},
// Error callback
onTokenValidationError: (error) => {
console.log('Token validation failed:', error);
},
}}
onReady={() => console.log('Auth initialized')}
>
<App />
</AuthProvider>TypeScript Support
Fully typed with comprehensive TypeScript definitions:
import type {
User,
AuthState,
LoginCredentials,
RegisterCredentials,
AuthConfig,
} from '@loonylabs/react-native-offline-auth';Testing
The library includes test infrastructure:
npm test # Run tests
npm run test:watch # Watch mode
npm run test:coverage # Coverage reportNote: We're actively working on expanding test coverage. Contributions welcome!
Architecture
┌─────────────────────────────────────────────┐
│ React Components │
│ (useAuth hook) │
└─────────────────┬───────────────────────────┘
│
┌─────────────────▼───────────────────────────┐
│ AuthProvider │
│ (Zustand Store + Context) │
└─────────────────┬───────────────────────────┘
│
┌─────────────────▼───────────────────────────┐
│ AuthService │
│ (Business Logic + Validation) │
└─────────────────┬───────────────────────────┘
│
┌─────────────────▼───────────────────────────┐
│ AuthStorage │
│ (AsyncStorage Wrapper) │
└─────────────────────────────────────────────┘Best Practices
✅ DO
- Use guest mode for better onboarding
- Load auth state on app start
- Handle offline scenarios gracefully
- Validate tokens in background
- Cache user data locally
❌ DON'T
- Wait for API calls on app start
- Logout users on network errors
- Block UI during token validation
- Store sensitive data beyond JWT token
- Force registration before trying the app
Compatibility
- React Native: 0.70+
- Expo: ✅ Compatible (SDK 47+)
- React Native Web: ✅ Compatible
- iOS: ✅ Tested
- Android: ✅ Tested
Contributing
Contributions are welcome! Please read our Contributing Guide first.
License
MIT © LoonyLabs
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Acknowledgments
Built with:
- Zustand - State management
- AsyncStorage - Persistent storage
- TypeScript - Type safety
Made with ❤️ by Loonylabs
