Skip to content

Zoldytech/react-native-expo-clerk-starter

Repository files navigation

React Native Expo Clerk Starter

A production-ready React Native starter template with comprehensive authentication, user profile management, and modern UI/UX - built with Expo, Clerk, and NativeWind.

✨ What's Included

This starter provides a complete authentication and user management system that you can use as a foundation for your React Native apps. Everything is type-safe, thoroughly tested, and follows modern best practices.

πŸ” Complete Authentication System

  • Unified "Continue with..." Flow - Modern single-page auth (like lu.ma)
  • Email/Password Authentication with proper validation
  • Social OAuth - Google & Apple (with proper error handling)
  • Email Verification with resend functionality
  • Password Reset flow
  • Type-safe Forms with React Hook Form + Zod validation

πŸ‘€ User Profile Management

  • Profile Settings with image upload
  • Username Editing with validation
  • Email Management - Add, verify, delete multiple emails
  • Phone Number Management - Add, verify, delete phone numbers
  • Connected Accounts - Link/unlink Google, Apple accounts
  • Security Settings - Password change, 2FA setup, passkey support

πŸ”’ Security Features

  • Passkey Support (when available in Clerk SDK)
  • Two-Factor Authentication setup (TOTP)
  • Secure Token Storage with expo-secure-store
  • Proper Error Handling with user-friendly messages
  • OAuth Security - Proper cleanup on cancellation/failure

🎨 Modern UI/UX

  • NativeWind - Tailwind CSS for React Native
  • Reusable Components - DRY principle, no code duplication
  • Responsive Design - Works on all screen sizes
  • Loading States - Proper UI feedback for all actions
  • Platform-specific Components - iOS and Web optimizations

πŸ›‘οΈ Type Safety

  • 100% TypeScript - No any types in production code
  • Clerk Type Integration - Proper typing for all Clerk resources
  • Form Validation - Runtime + compile-time type checking
  • Error Type Guards - Safe error handling patterns

πŸš€ Quick Start

Prerequisites

1. Clone & Install

git clone <your-repo>
cd mobile-app
npm install

2. Environment Setup

Create a .env file:

EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_your-key-here

3. Clerk Configuration

  1. Create a new Clerk application
  2. Enable Email and OAuth providers (Google, Apple)
  3. Configure OAuth redirect URLs:
    • Development: exp://127.0.0.1:19000/--/oauth-callback
    • Production: Your app's deep link scheme

4. Start Development

npx expo start

πŸ“± Authentication Flows

Unified Continue Flow (/continue)

Modern single-page authentication similar to lu.ma:

  1. Email Entry - User enters email
  2. Smart Routing - Automatically detects existing users
  3. Sign In - Existing users enter password
  4. Sign Up - New users complete profile (name + password)
  5. Verification - Email verification when needed

Classic Flows (Still Available)

  • Sign In (/sign-in) - Traditional email/password
  • Sign Up (/sign-up) - Traditional registration
  • Verification (/verify) - Email verification
  • Forgot Password (/forgot-password) - Password reset

Profile Management

Complete user profile system accessible after authentication:

  • Profile Details - Name, username, profile image
  • Email Management - Multiple emails, verification
  • Phone Management - Add/remove phone numbers
  • Connected Accounts - OAuth account linking
  • Security Settings - Password, 2FA, passkeys

πŸ—οΈ Project Structure

mobile-app/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ (auth)/                    # Authentication screens
β”‚   β”‚   β”œβ”€β”€ _components/           # Shared auth components
β”‚   β”‚   β”‚   └── AuthContainer.tsx  # Layout wrapper
β”‚   β”‚   β”œβ”€β”€ continue.tsx           # Unified auth flow ⭐
β”‚   β”‚   β”œβ”€β”€ sign-in.tsx           # Classic sign in
β”‚   β”‚   β”œβ”€β”€ sign-up.tsx           # Classic sign up
β”‚   β”‚   β”œβ”€β”€ verify.tsx            # Email verification
β”‚   β”‚   └── forgot-password.tsx   # Password reset
β”‚   β”œβ”€β”€ (tabs)/                   # Main app (protected)
β”‚   β”‚   β”œβ”€β”€ index.tsx             # Home tab
β”‚   β”‚   β”œβ”€β”€ explore.tsx           # Explore tab
β”‚   β”‚   └── profile/              # Profile management
β”‚   β”‚       β”œβ”€β”€ index.tsx         # Profile overview
β”‚   β”‚       └── settings.tsx      # Profile settings
β”‚   β”œβ”€β”€ index.tsx                 # Welcome/landing screen
β”‚   └── _layout.tsx               # Root layout + Clerk provider
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   β”œβ”€β”€ SignInWith.tsx        # Social auth buttons
β”‚   β”‚   β”œβ”€β”€ SignOutButton.tsx     # Sign out functionality
β”‚   β”‚   └── UserProfileSettings/  # Complete profile system
β”‚   β”‚       β”œβ”€β”€ ProfileSection.tsx      # Main profile component
β”‚   β”‚       β”œβ”€β”€ SecuritySection.tsx     # Security settings
β”‚   β”‚       └── components/             # Sub-components
β”‚   β”‚           β”œβ”€β”€ ProfileHeader.tsx   # Profile image/name
β”‚   β”‚           β”œβ”€β”€ EmailManagement.tsx # Email management
β”‚   β”‚           β”œβ”€β”€ PhoneManagement.tsx # Phone management
β”‚   β”‚           └── ConnectedAccounts.tsx # OAuth accounts
β”‚   β”œβ”€β”€ FormInput.tsx             # Type-safe form input
β”‚   └── ui/                       # UI components
β”œβ”€β”€ constants/
β”‚   β”œβ”€β”€ Colors.ts                 # Theme colors
β”‚   └── Config.ts                 # App configuration
└── hooks/
    β”œβ”€β”€ useColorScheme.ts         # Theme detection
    └── useThemeColor.ts          # Color theming

🎯 Key Features Explained

Type-Safe Authentication

All forms use React Hook Form + Zod for validation:

const signInSchema = z.object({
  identifier: z.string().email('Please enter a valid email address'),
  password: z.string().min(8, 'Password should be at least 8 characters long'),
})

Error Handling Pattern

Consistent error handling across all components:

catch (error: unknown) {
  if (isClerkAPIResponseError(error)) {
    const message = error.errors?.[0]?.longMessage || 'Default message'
    Alert.alert('Error', message)
  } else {
    Alert.alert('Error', 'Something went wrong')
  }
}

OAuth Integration

Proper OAuth implementation with cleanup:

// Dynamic redirect URI generation
const redirectUri = AuthSession.makeRedirectUri()

// Proper cleanup on cancellation
if (result.type === 'cancel') {
  await externalAccount.destroy() // Clean up pending connection
}

Reusable Components

DRY principle with reusable, type-safe components:

<FormInput
  control={form.control}
  name="email"
  label="Email Address"
  placeholder="Enter your email"
  keyboardType="email-address"
  autoComplete="email"
/>

πŸ”§ Customization

Styling

The app uses NativeWind (Tailwind CSS for React Native):

  • No custom StyleSheets needed
  • Consistent spacing and colors
  • Easy to customize with Tailwind classes

Branding

Update branding in:

  • constants/Config.ts - App configuration
  • constants/Colors.ts - Theme colors
  • app.json - App metadata

Authentication Options

Configure in Clerk dashboard:

  • Enable/disable OAuth providers
  • Customize email templates
  • Set up custom domains
  • Configure session settings

πŸ“š Available Scripts

# Development
npm start                 # Start Expo development server
npm run ios              # Run on iOS simulator
npm run android          # Run on Android emulator
npm run web              # Run in web browser

# Code Quality
npm run lint             # ESLint check
npm run type-check       # TypeScript check
npm test                 # Run tests (if configured)

# Build
npm run build            # Build for production

πŸ”’ Security Best Practices

This starter follows security best practices:

  • βœ… No hardcoded secrets - Environment variables only
  • βœ… Secure token storage - Using expo-secure-store
  • βœ… Input validation - Client + server-side validation
  • βœ… Error handling - No sensitive data in error messages
  • βœ… OAuth security - Proper redirect URI handling
  • βœ… Type safety - Prevents runtime errors

🚒 Production Deployment

Environment Variables

Update for production:

EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_your-production-key

OAuth Redirect URIs

Configure production URLs in Clerk:

  • iOS: your-app-scheme://oauth-callback
  • Android: your-app-scheme://oauth-callback
  • Web: https://your-domain.com/oauth-callback

App Store Requirements

  • Test all OAuth flows on device
  • Verify email deliverability
  • Test password reset flows
  • Ensure accessibility compliance

🀝 Contributing

This is a starter template, but contributions are welcome:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

πŸ“„ License

MIT License - feel free to use this starter for any project.

πŸ†˜ Support


Built with ❀️ by Zoldytech

This starter saves you weeks of development time by providing a complete, production-ready authentication system with proper TypeScript integration and modern UI/UX patterns.