NativeCraft

React Native CLI

React Native 0.81.4TypeScript 5.8.3Redux 5.0.1React Navigation 7.1Firebase 23.4.0New Architecture Ready

Project Overview

A modern, production-ready React Native boilerplate with TypeScript support, focusing on best practices, scalability, and developer experience. This boilerplate includes authentication flows, theming support, RTL handling, Firebase push notifications, React Native New Architecture support, and a robust project structure.

Features

  • ๐Ÿ” Authentication Flow: Complete login and OTP verification using react-native-otp-entry
  • ๐Ÿ”” Push Notifications: Firebase Cloud Messaging integration with secure token storage
  • ๐ŸŒ“ Theme Support: Dynamic light/dark theme switching with context
  • ๐ŸŒ Multi-language Support: RTL/LTR with i18next integration
  • ๐Ÿ“ฑ Responsive Design: Adapts to different screen sizes with proper scaling
  • ๐Ÿงฉ Modular Architecture: Clean and maintainable code structure
  • ๐Ÿ”„ State Management: Redux Toolkit with proper action handling
  • ๐ŸŽจ SVG Support: Vector graphics with react-native-svg and transformer
  • ๐Ÿ”’ Secure Storage: Encrypted storage with rn-secure-storage
  • ๐Ÿ’ซ Animations: Smooth animations with react-native-reanimated
  • ๐Ÿš€ Fast Development: Hot reloading and developer tools
  • ๐Ÿ›ก๏ธ Type Safety: Full TypeScript integration
  • ๐ŸŽฏ Navigation: React Navigation 7 with bottom tabs and native stack
  • โšก New Architecture: React Native New Architecture (Fabric & TurboModules) ready
  • ๐Ÿ“‹ Clipboard Support: Cross-platform clipboard functionality

Project Architecture

.
โ”œโ”€โ”€ android/                  # Android native code
โ”œโ”€โ”€ ios/                     # iOS native code
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ assets/             # Images, fonts, etc.
โ”‚   โ”œโ”€โ”€ components/         # Reusable UI components
โ”‚   โ”œโ”€โ”€ config/             # App configuration
โ”‚   โ”œโ”€โ”€ context/            # React Context providers
โ”‚   โ”œโ”€โ”€ helper/             # Helper services (notifications, etc.)
โ”‚   โ”œโ”€โ”€ hooks/              # Custom React hooks
โ”‚   โ”œโ”€โ”€ lang/               # i18n translations
โ”‚   โ”œโ”€โ”€ models/             # TypeScript interfaces
โ”‚   โ”œโ”€โ”€ navigation/         # Navigation setup
โ”‚   โ”œโ”€โ”€ redux/              # State management
โ”‚   โ”œโ”€โ”€ screens/            # Screen components
โ”‚   โ”œโ”€โ”€ styles/             # Global styles
โ”‚   โ”œโ”€โ”€ typings/           # Global TypeScript types
โ”‚   โ””โ”€โ”€ utils/             # Utility functions
โ”œโ”€โ”€ patches/                # Patch files for dependencies
โ”œโ”€โ”€ vendor/                # Vendor files
โ”œโ”€โ”€ .eslintrc.js           # ESLint configuration
โ”œโ”€โ”€ .prettierrc.js         # Prettier configuration
โ”œโ”€โ”€ babel.config.js        # Babel configuration
โ”œโ”€โ”€ metro.config.js        # Metro bundler configuration
โ”œโ”€โ”€ tsconfig.json          # TypeScript configuration
โ””โ”€โ”€ package.json           # Project dependencies

Technology Stack

Core

  • React Native: v0.81.4 (New Architecture Ready)
  • TypeScript: v5.8.3
  • React: v19.1.0

State Management & Data Flow

  • Redux: v5.0.1
  • React Redux: v9.2.0
  • Redux Toolkit: v2.8.2

Navigation

  • @react-navigation/native: v7.1.17
  • @react-navigation/native-stack: v7.3.26
  • @react-navigation/bottom-tabs: v7.4.7
  • react-native-safe-area-context: v5.6.1
  • react-native-screens: v4.15.4

UI & Animations

  • react-native-reanimated: v4.1.0
  • react-native-worklets: v0.5.0
  • react-native-svg: v15.12.1
  • react-native-svg-transformer: v1.5.1
  • react-native-modal: v14.0.0-rc.1
  • react-native-bootsplash: v6.3.10

Internationalization

  • i18next: v25.4.2
  • react-i18next: v15.7.3
  • intl-pluralrules: v2.0.1

Security & Storage

  • rn-secure-storage: v3.0.1
  • @react-native-clipboard/clipboard: v1.16.3

Firebase

  • @react-native-firebase/app: v23.4.0
  • @react-native-firebase/messaging: v23.4.0
  • axios: v1.11.0

Development & Testing

  • jest: v29.6.3
  • eslint: v8.19.0
  • prettier: v2.8.8
  • babel-plugin-module-resolver: v5.0.2
  • patch-package: v8.0.0

Setup and Installation

Prerequisites

  • Node.js (LTS version)
  • Ruby (for iOS development)
  • CocoaPods (for iOS development)
  • Android Studio (for Android development)
  • Xcode (for iOS development)

Installation Steps

1. Clone the repository:

git clone <repository-url>
cd rn_boilerplate

2. Install dependencies:

npm install
# or
yarn install

3. iOS specific setup:

cd ios
pod install
cd ..

4. Firebase Setup (for push notifications):

Android:

  • Place your google-services.json file in android/app/
  • The project is already configured with Firebase plugins

iOS:

  • Place your GoogleService-Info.plist file in ios/rn_boilerplate/
  • Run cd ios && pod install after adding the file

5. Start the application:

# Start Metro bundler
npm start
# or
yarn start

# iOS
npm run ios
# or
yarn ios

# Android
npm run android
# or
yarn android

Core Features Implementation

Theme System

The app uses a context-based theme system:

// Usage in components
const { theme } = useTheme();
const colors = Colors[theme];

const styles = StyleSheet.create({
  container: {
    backgroundColor: colors.background
  }
});

Internationalization

Built-in i18next integration:

// Using translations
import { useTranslation } from 'react-i18next';

const { t } = useTranslation();
<TextComp text={t('WELCOME')} />

Secure Storage

// Using secure storage
import { secureStorage } from '@/utils/secureStorage';

await secureStorage.setItem('key', 'value');
const value = await secureStorage.getItem('key');
await secureStorage.setObject('userData', { name: 'John', age: 30 });
const userData = await secureStorage.getObject('userData');

Firebase Push Notifications

The app includes Firebase Cloud Messaging for push notifications:

// Request notification permissions and get FCM token
import { requestUserPermission } from '@/helper/notificationService';

// Call this in your App.tsx or main component
await requestUserPermission();

Key Features:

  • Automatic FCM token generation and secure storage
  • Permission handling for both iOS and Android
  • Token refresh and management
  • Secure token storage using encrypted storage

React Native New Architecture

This boilerplate is New Architecture Ready and supports:

Fabric (New Renderer):

  • Improved performance and reduced memory usage
  • Better interoperability between JavaScript and native code
  • Enhanced type safety with TypeScript

TurboModules:

  • Lazy loading of native modules
  • Better performance for native module calls
  • Improved developer experience

To enable New Architecture:

  1. Android: Set newArchEnabled=true in android/gradle.properties
  2. iOS: Set RCT_NEW_ARCH_ENABLED=1 in your Podfile
  3. Run cd ios && pod install && cd ..
  4. Clean and rebuild your project

Available Scripts

  • npm start - Start the Metro bundler
  • npm run ios - Run the iOS app
  • npm run android - Run the Android app
  • npm run lint - Run ESLint
  • npm run test - Run Jest tests

Core Concepts and Implementation

Theme System (Dark/Light)

The app uses a Context-based theming system that allows for seamless switching between light and dark modes:

// src/context/ThemeContext.tsx
import React, { createContext, useState, useEffect, useContext } from 'react';
import { secureStorage } from '@/utils/secureStorage';
import { Colors, ThemeType } from '@/styles/colors';

// Usage in components
const { theme, toggleTheme } = useTheme();
const colors = Colors[theme];

Key Features:

  • Theme persistence using Secure Storage
  • Dynamic theme switching with context API
  • Semantic color naming that adapts to current theme
  • Support for system theme detection

Using Theme Colors:

// Component example
import { useTheme } from '@/context/ThemeContext';
import { Colors } from '@/styles/colors';

const MyComponent = () => {
const { theme } = useTheme();
const colors = Colors[theme];

return (
<View style={{ backgroundColor: colors.background }}>
<Text style={{ color: colors.text }}>Hello World</Text>
</View>
);
};

Font Management

Fonts are loaded at application startup and made available through a centralized font family object:

// Font loading in App.tsx
const [loaded, error] = useFonts({
"Inter-Regular": require("./src/assets/fonts/Inter-Regular.ttf"),
"Inter-Bold": require("./src/assets/fonts/Inter-Bold.ttf"),
"Inter-Medium": require("./src/assets/fonts/Inter-Medium.ttf"),
"Inter-SemiBold": require("./src/assets/fonts/Inter-SemiBold.ttf"),
});

// Usage with fontFamily utility
import fontFamily from '@/styles/fontFamily';

const styles = StyleSheet.create({
title: {
fontFamily: fontFamily.bold,
fontSize: 18,
}
});

Font Family Structure:

// src/styles/fontFamily.ts
export default {
regular: 'Inter-Regular',
medium: 'Inter-Medium',
semiBold: 'Inter-SemiBold',
bold: 'Inter-Bold',
};

Internationalization (I18n)

The app supports multiple languages with full RTL layout support using i18next:

// src/lang/index.ts
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import 'intl-pluralrules';
import en from './en.json';
import ar from './ar.json';

i18n
.use(initReactI18next)
.init({
resources: {
en: { translation: en },
ar: { translation: ar }
},
lng: 'en',
fallbackLng: 'en',
interpolation: {
escapeValue: false
}
});

export default i18n;

Translation Files Structure:

// en.json
{
"LOGIN": "Login",
"WELCOME_MESSAGE": "Welcome to NativeCraft"
}

// ar.json
{
"LOGIN": "ุชุณุฌูŠู„ ุงู„ุฏุฎูˆู„",
"WELCOME_MESSAGE": "ู…ุฑุญุจู‹ุง ุจูƒ ููŠ NativeCraft"
}

Using Translations:

// With the TextComp wrapper component
<TextComp text="LOGIN" />

// With variable substitution
<TextComp text="HELLO_USER" values={{ name: user.name }} />

RTL Support:

// Custom hook for RTL detection
import { useTranslation } from 'react-i18next';

export default function useIsRTL() {
const { i18n } = useTranslation();
return i18n.language === 'ar';
}

// Usage in styles
const styles = StyleSheet.create({
container: {
flexDirection: isRTL ? 'row-reverse' : 'row',
textAlign: isRTL ? 'right' : 'left',
}
});

Reusable Components

The app uses a set of standardized components to ensure consistency:

TextComp - Text Component with i18n Support:

// Usage
<TextComp text="WELCOME" />
<TextComp isDynamic text="Hello World" /> // Direct text without translation

ButtonComp - Customizable Button:

// Usage
<ButtonComp 
text="LOGIN" 
onPress={handleLogin}
variant="primary" // or "secondary", "outline", etc.
isLoading={isLoading}
/>

TextInputComp - Custom Text Input:

// Usage
<TextInputComp
label="EMAIL"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
isPassword={false}
/>

HeaderComp - App Header:

// Usage
<HeaderComp 
title="PROFILE" 
showBack={true}
onBackPress={() => navigation.goBack()}
/>

WrapperContainer - Safe Area Wrapper:

// Usage
<WrapperContainer>
{/* Screen content */}
</WrapperContainer>

State Management with Redux

The app uses Redux Toolkit for centralized state management:

// Store setup
// src/redux/store.ts
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers';

const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => 
getDefaultMiddleware({
serializableCheck: false,
}),
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;

Reducers Structure:

// src/redux/reducers/index.ts
import { combineReducers } from '@reduxjs/toolkit';
import authReducer from './authSlice';
import appReducer from './appSlice';

const rootReducer = combineReducers({
auth: authReducer,
app: appReducer,
});

export default rootReducer;

Actions Structure:

// src/redux/actions/index.ts
import * as authActions from './authActions';
import * as appActions from './appActions';

export default {
...authActions,
...appActions,
};

Using Redux in Components:

// In a component
import { useDispatch, useSelector } from 'react-redux';
import actions from '@/redux/actions';
import { RootState } from '@/redux/store';

const Component = () => {
const dispatch = useDispatch();
const { user } = useSelector((state: RootState) => state.auth);

const handleLogin = async () => {
await dispatch(actions.login(credentials));
};

return (/* Component JSX */);
};

API Integration

The app uses a centralized API service based on Axios:

// src/config/api.ts
import axios from 'axios';
import { API_BASE_URL } from '@/config/constants';

const apiInstance = axios.create({
baseURL: API_BASE_URL,
timeout: 30000,
headers: {
'Content-Type': 'application/json',
},
});

// Request interceptor
apiInstance.interceptors.request.use(
async (config) => {
// Add authorization token if available
const token = await getAuthToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);

// Response interceptor
apiInstance.interceptors.response.use(
(response) => response.data,
(error) => {
// Handle errors (401, 403, 500, etc.)
return Promise.reject(error);
}
);

export default apiInstance;

API Actions:

// src/redux/actions/authActions.ts
import apiInstance from '@/config/api';
import { createAsyncThunk } from '@reduxjs/toolkit';

export const login = createAsyncThunk(
'auth/login',
async (credentials, { rejectWithValue }) => {
try {
const response = await apiInstance.post('/auth/login', credentials);
return response;
} catch (error) {
return rejectWithValue(error.response?.data || 'Login failed');
}
}
);

Secure Local Storage

The app uses Expo's SecureStore for encrypted storage:

// src/utils/secureStorage.ts
import * as SecureStore from 'expo-secure-store';

// Storage keys
export const STORAGE_KEYS = {
AUTH_TOKEN: 'AUTH_TOKEN',
USER_DATA: 'USER_DATA',
LANGUAGE: 'LANGUAGE',
THEME: 'THEME',
} as const;

type StorageKeyType = keyof typeof STORAGE_KEYS;

export const secureStorage = {
async setItem(key: StorageKeyType, value: string) {
try {
await SecureStore.setItemAsync(STORAGE_KEYS[key], value);
} catch (error) {
console.error('Error storing value:', error);
}
},

async getItem(key: StorageKeyType) {
try {
return await SecureStore.getItemAsync(STORAGE_KEYS[key]);
} catch (error) {
console.error('Error retrieving value:', error);
return null;
}
},

async removeItem(key: StorageKeyType) {
try {
await SecureStore.deleteItemAsync(STORAGE_KEYS[key]);
} catch (error) {
console.error('Error removing value:', error);
}
},

// Helper for storing objects
async setObject(key: StorageKeyType, value: object) {
try {
const jsonValue = JSON.stringify(value);
await this.setItem(key, jsonValue);
} catch (error) {
console.error('Error storing object:', error);
}
},

// Helper for retrieving objects
async getObject(key: StorageKeyType) {
try {
const jsonValue = await this.getItem(key);
return jsonValue ? JSON.parse(jsonValue) : null;
} catch (error) {
console.error('Error retrieving object:', error);
return null;
}
},
};

SVG Integration

The app uses react-native-svg and react-native-svg-transformer for SVG support:

// In components
import Logo from '@/assets/icons/logo.svg';

const Component = () => {
return (
<View>
<Logo width={100} height={100} fill={colors.primary} />
</View>
);
};

Responsive Styling

The app uses a scaling utility for responsive dimensions:

// src/styles/scaling.ts
import { Dimensions } from 'react-native';

const { width, height } = Dimensions.get('window');

// Guideline sizes are based on standard ~5" screen mobile device
const guidelineBaseWidth = 350;
const guidelineBaseHeight = 680;

export const horizontalScale = (size: number) => (width / guidelineBaseWidth) * size;
export const verticalScale = (size: number) => (height / guidelineBaseHeight) * size;
export const moderateScale = (size: number, factor = 0.5) => 
size + (horizontalScale(size) - size) * factor;

Using Scale in Styles:

import { moderateScale } from '@/styles/scaling';

const styles = StyleSheet.create({
container: {
padding: moderateScale(16),
marginBottom: moderateScale(20),
},
title: {
fontSize: moderateScale(18),
},
});

Navigation Setup

The app uses React Navigation 7.x with a structured approach:

// src/navigation/Routes.tsx
import React, { useEffect, useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import AuthStack from './stacks/AuthStack';
import MainStack from './stacks/MainStack';
import { useSelector } from 'react-redux';
import { RootState } from '@/redux/store';

const Routes = () => {
const { isAuthenticated } = useSelector((state: RootState) => state.auth);

return (
<NavigationContainer>
{isAuthenticated ? <MainStack /> : <AuthStack />}
</NavigationContainer>
);
};

export default Routes;

Navigation Types:

// src/navigation/types.ts
export type AuthStackParamList = {
Login: undefined;
Signup: undefined;
OTPVerification: { email: string };
};

export type MainStackParamList = {
Home: undefined;
Profile: { userId: string };
Settings: undefined;
};

export type TabParamList = {
HomeTab: undefined;
ProfileTab: undefined;
SettingsTab: undefined;
};

Why This Architecture?

Modularity and Maintainability

This modular approach separates concerns clearly, making the codebase more maintainable:

  1. Component Reusability: UI components are reusable across screens
  2. Business Logic Separation: Redux actions/reducers separate business logic from UI
  3. Theming Abstraction: Theme is centralized and easily switchable
  4. Navigation Structure: Clear navigation hierarchy

Scalability

The architecture is designed to scale with your application:

  1. Feature Isolation: Add new features by adding new directories/modules
  2. Consistent Patterns: New developers can follow established patterns
  3. Performance Optimization: Easy to optimize specific components
  4. Testing: Components are isolated and easier to test

TypeScript Integration

TypeScript provides:

  1. Type Safety: Catch errors at compile time
  2. IDE Support: Better autocomplete and documentation
  3. Refactoring Confidence: Safer refactoring with type checking
  4. API Contract Enforcement: Interface definitions for API responses

Best Practices

Code Style

  • Use functional components with hooks
  • Keep components small and focused
  • Use descriptive variable and function names
  • Document complex logic with comments

Performance Considerations

  • Use React.memo for pure components
  • Use useCallback for event handlers
  • Use useMemo for expensive computations
  • Implement virtualized lists for long scrolling content

Security Best Practices

  • Store sensitive data in SecureStore
  • Use HTTPS for all API requests
  • Sanitize user inputs
  • Implement proper token refresh mechanism