A curated collection of 28 standalone React Native example projects, each demonstrating a specific concept, library, or architecture pattern. Projects are independent — each has its own package.json, android/, and ios/ directories.
- Platform: React Native (iOS + Android)
- Language: TypeScript (all projects)
- JS Engine: Hermes (default on RN 0.70+)
- RN Version Range: 0.68 (oldest) → 0.84 (newest)
| Folder | Concept / Purpose | RN Version | Key Libraries |
|---|---|---|---|
AbsoluteImports |
Path aliasing with @app/* imports |
0.71.8 | babel-plugin-module-resolver |
analytics |
Analytics native module (Turbo Module) | 0.84.0 | CodeGen, Kotlin (useKotlin: true) |
animated_flatlist |
FlatList + Reanimated scroll animations | 0.71.3 | react-native-reanimated 3.x |
AnimatedInput |
Enter/exit input animations (core only) | 0.72.6 | — |
bottomsheet_gesturehandler |
Gesture-driven bottom sheet modal | 0.71.3 | gesture-handler 2.x, reanimated 3.x |
carousel |
Image carousel with SVG icons | 0.71.8 | react-native-svg, react-native-vector-icons |
DimensionStrategy |
Responsive layout / safe area strategy | 0.83.1 | react-native-safe-area-context 5.x |
drag_reactangle_reanimated |
Draggable element with gestures | 0.71.3 | gesture-handler 2.x, reanimated 3.x |
grpc_react_native |
gRPC client (alternative to REST/GraphQL) | 0.71.3 | gRPC native setup |
interpolate_scrollview_reanimated |
Scroll interpolation animations | 0.71.3 | react-native-reanimated 3.x |
lottieAndRive |
Lottie vs Rive animation comparison | 0.84.0 | lottie-react-native 7.x, rive-react-native 9.x |
mmkv |
JSI-based key-value storage | 0.83.1 | react-native-mmkv 4.x, react-native-nitro-modules |
mono_repo_yarn |
Yarn Workspaces monorepo setup | N/A | Yarn workspaces (packages/*) |
mvvm_example |
MVVM architecture pattern | 0.71.6 | @reduxjs/toolkit, react-redux, react-navigation |
mypodcast |
Full podcast/audio streaming app | 0.74.1 | @apollo/client, react-native-track-player |
NativeModuleWithKotlin |
Kotlin native bridge modules | 0.71.10 | react-native-super-grid |
NativeWindDLS |
Tailwind CSS via NativeWind | 0.83.1 | nativewind 4.x, tailwindcss 3.x |
otpWidget |
OTP input widget | 0.71.8 | react-native-vector-icons, styled-components |
QrAndBarcodeScanner |
Camera-based QR/barcode scanning | 0.71.7 | react-native-vision-camera 2.x |
react-native-background-timer-workmanager |
Android WorkManager background timers (npm package) | 0.68.1 | — |
ReduxSaga |
Redux + Saga side-effect management | 0.83.1 | @reduxjs/toolkit 2.x, redux-saga 1.4.x |
RootDetection |
Root/jailbreak device detection | 0.83.1 | jail-monkey, react-native-device-info |
Storybook |
On-device component library/design system | 0.73.2 | @storybook/react-native 6.x, styled-components |
suspense_and_freeze |
React 18 Suspense + React Freeze | 0.71.7 | react-freeze |
TurboDemo |
Turbo Modules (New Architecture) demo | 0.83.1 | CodeGen config |
turbo-secure-storage |
Published Turbo Module — Keychain/KeyStore secure storage | 0.68.0 | C++ JSI bindings, CodeGen |
watermelon_db_jsi |
WatermelonDB JSI SQLite local storage | 0.71.4 | @nozbe/watermelondb, recompose |
widgetApp |
Home screen widget implementation | 0.73.7 | — |
- TypeScript only — no plain
.jsfiles in source - Use
interfacefor object shapes,typefor unions/aliases - No
anytypes — use proper generics orunknownwhere needed - Prefer explicit return types on all exported functions and components
- Functional components only — no class components
- Use
React.FC<Props>or explicit prop typing - Keep components in their own files; no multi-component files
- Prefer named exports over default exports for components
- Use
StyleSheet.create()by default in all non-NativeWind projects NativeWindDLSproject uses Tailwind class strings — noStyleSheetthereotpWidgetandStorybookusestyled-components— follow existing pattern per project- No inline style objects in JSX (e.g.,
style={{ margin: 10 }}) — always useStyleSheet
- Use
FlatListorFlashListfor all lists — neverScrollView+.map() - Set
keyExtractorexplicitly — never rely on index as key - Optimize with
getItemLayoutfor fixed-height items - Avoid inline
renderItemarrow functions — define outside component
- Always set
useNativeDriver: trueonAnimatedAPI calls (non-layout props only) - For layout animations or complex interactions → use
react-native-reanimatedwith worklets - Pair
react-native-gesture-handlerwith Reanimated for gesture-driven animations - Postpone heavy work during animations using
InteractionManager.runAfterInteractions()
- Never use AsyncStorage for sensitive data — use
turbo-secure-storage(Keychain/KeyStore) or MMKV - Use
react-native-mmkvfor high-performance key-value storage (JSI-based, synchronous) - Use WatermelonDB for complex relational/offline-first data
- No
console.login committed code - No commented-out code blocks
- No unused imports or variables
- Handle loading and error states explicitly in all data-fetching components
Projects: TurboDemo, turbo-secure-storage, analytics, mmkv
- Define specs in TypeScript using
TurboModuleRegistry - Run CodeGen to generate native scaffolding:
cd android && ./gradlew generateCodegenArtifactsFromSchema - C++ implementation in
turbo-secure-storage; Kotlin inanalytics - Cannot use Remote JS Debugger with Turbo Modules — use Flipper or Chrome DevTools via Hermes
Project: mvvm_example
View → ViewController → ViewModel → Model
↑
Provider (dependency injection)
ViewModelis a plain JS class — no framework couplingViewControllercan talk to multiple ViewModelsModelhandles network/database/services
Project: ReduxSaga
- Use
@reduxjs/toolkitslices for reducers + actions - Sagas handle async side effects (API calls, timers)
- Redux Toolkit's
createSliceauto-generates action types
Project: mono_repo_yarn
- Packages live under
packages/* - Hoist shared dependencies to root
node_modules - Use
nohoistfor React Native native dependencies
- Define animations using
useSharedValue+useAnimatedStyle - Run worklets on UI thread — no bridge overhead
- Supports animating ALL style props (including height, color) — unlike core
Animated
- Use
classNameprop instead ofstyle - Configure
tailwind.config.jswithcontentpaths - Requires
react-native-css-interop patch-packagepatches are applied post-install
- Requires camera permissions (both platforms)
- Use
useCameraDevices()+useCodeScanner()hooks - Frame processors run via JSI worklets
- Uses
@observable+@fielddecorators — enableexperimentalDecoratorsin tsconfig recomposeHOCs wrap components with observables- JSI-based SQLite: fast synchronous queries
- Lottie: JSON from Adobe AE via BodyMovin plugin; static, limited runtime control
- Rive: State-machine driven; smaller file size; more FPS; full runtime control
- Prefer Rive for interactive animations; Lottie for simple playback
Each project is a standalone RN app. Run from within the project folder:
# Install dependencies
npm install
# or for Node 20+ projects (DimensionStrategy, TurboDemo):
npm install # ensure node >= 20
# iOS
npx pod-install # install CocoaPods
npx react-native run-ios
# Android
npx react-native run-android
# Metro bundler
npx react-native start --reset-cache
# TypeScript check
npx tsc --noEmit
# Check unused dependencies
npx depcheckUse this flow for any new Expo-based project (generates native folders, skips Expo Go):
# Step 1 — Create the project
npx create-expo-app@latest MyApp --template default@sdk-55
cd MyApp
# Step 2 — Install expo-dev-client
npx expo install expo-dev-client
# Step 3 — Prebuild (generates android/ and ios/ native folders)
npx expo prebuild --clean
# Step 4 — Build and run your custom dev client
# Android
npx expo run:android
ELECTRON_DISABLE_SANDBOX=1 npx expo run:android; ## For ubuntu
# iOS
npx expo run:ios
# Step 5 — Subsequent development (JS-only changes)
# Custom dev client is already installed; this just starts Metro
npx expo startAfter Step 4 you never need Expo Go. Fast refresh works as normal via your own binary.
Always use npx expo install instead of npm install / yarn add for packages with Expo-managed native dependencies:
npx expo install expo-camera
npx expo install expo-location react-native-mapsnpx expo install resolves the exact version compatible with your current SDK — e.g. for SDK 55 it pins expo-camera@55.x.x. Using npm install without a version can pull in a build targeting a different SDK and cause subtle, hard-to-debug breakage.
Use npm install / yarn add only for pure-JS packages that have no Expo SDK coupling (e.g. lodash, zod, date-fns).
| Projects | Minimum Node |
|---|---|
DimensionStrategy, TurboDemo |
Node >= 20 |
mypodcast |
Node >= 18 |
| All others | Node >= 16 |
When adding features to any project in this repo:
- Lists use
FlatList/FlashList, notScrollView.map - Animations use
useNativeDriver: trueor Reanimated worklets - No heavy computation on the JS thread during animations
- Images are appropriately sized (avoid 1080p in lists)
-
React.memoapplied to expensive list item components - Sensitive data in Keychain/MMKV, not AsyncStorage
- No
console.logstatements committed
- Hermes + Flipper: Use for Turbo Module projects (no remote debugger)
- React DevTools:
npx react-devtoolsfor component tree inspection - Metro logs:
npx react-native startshows bundler errors - Android logs:
adb logcator Android Studio Logcat - iOS logs: Xcode console or
xcrun simctl spawn booted log stream
| Command | Purpose |
|---|---|
/react-native-best-practices |
Performance optimization guide (FPS, TTI, bundle size, memory leaks) |
/simplify |
Review changed code for quality, reuse, and efficiency |
/claude-api |
Build with the Claude / Anthropic API |
/keybindings-help |
Customize Claude Code keyboard shortcuts |