Here's how I'd start a React Native app today if I want it to be native: USE THE PLATFORM, don't reinvent the wheel. My must-haves:
- react-native-screens from
@swmansion, together with
@reactnavigation. Native stack, native tabs, formSheet for bottom sheets, native modals, SF Symbols, Material Symbols, etc. Keep an eye on v5.
- expo-ui from
@expo for SwiftUI and Jetpack Compose components in JSX. Missing one? Have AI write it and contribute it back.
- Nitro Modules from
@margelo_io for low-level, fast native code (Swift, Kotlin, C++). Some good examples: react-native-mmkv for key-value storage (a must), react-native-healthkit, react-native-nitro-fetch.
- expo-sqlite + drizzle-orm from
@DrizzleORM if you need a local database.
- Legend State from
@jmeistrich. Write proper selectors, watch your re-renders, and close subscriptions on unfocused screens (think Android onResume/onPause). Be methodical. This is not the web, and React Compiler won't do it for you.
- Do not block your app startup with anything. You should not need a splash screen if you don't want one.
Use whatever tools you want. But React Native does not mean your app isn't native under the hood. Your iOS and Android builds end up very, very different, on purpose. You're just using abstractions that smart people built and keep curating for you.
Do this and when something like the iPhone Duo comes out, your app just works on it. You were already using native navigation, sheets and components, so the platform adapts them for you.