Turning a Web App into Mobile: Migrating to React Native
Migrate a web app to React Native by sharing domain logic and API clients while rebuilding navigation, accessibility, storage, and interaction for native platforms. This revised guide emphasizes supported APIs, production tradeoffs, and an upgrade-friendly path without tying the advice to a calendar year.

Modern implementation baseline
Migrate a web app to React Native by sharing domain logic and API clients while rebuilding navigation, accessibility, storage, and interaction for native platforms.
Use TypeScript, the New Architecture, supported public APIs, and libraries that publish an explicit compatibility policy. Prefer framework-managed native dependencies when that reduces upgrade risk, and verify behavior in release builds on both platforms.
Recommended approach
- Inventory reusable logic separately from DOM-based UI.
- Build one vertical mobile workflow before broad migration.
- Design offline, deep-link, keyboard, and permission behavior explicitly.
Production checklist
- Test on representative Android and iOS devices, not only simulators.
- Profile startup, interaction latency, memory, and network failure states.
- Keep native dependencies compatible with the active React Native release line.
Authoritative references
Why migrate to React Native?
React Native remains a top choice for cross-platform development due to:
- Performance Boosts: Hermes, the standard JavaScript engine in supported React Native releases, improves startup and memory behavior, ideal for web-to-mobile transitions.
- Code Reusability: Share up to 80% of your JavaScript codebase from web (e.g., React) with minimal adjustments.
- Modern Ecosystem: Integration with TypeScript, React Navigation 7, and Reanimated 3 ensures a future-proof stack.
- Community Support: Active updates and a robust plugin ecosystem keep React Native relevant for startups and enterprises.
Prerequisites
Before starting, ensure you have:
- Node.js 20.x (LTS) and npm 10.x installed.
- React Native CLI or the current stable Expo SDK set up.
- A web app built with React 18.x (or a similar framework like Next.js).
- Basic knowledge of JavaScript/TypeScript and mobile development concepts.
Step-by-Step Migration Process
1. Assess Your Web App
What to Evaluate
- Component Structure: Identify reusable React components (e.g., buttons, forms).
- State Management: Check if you use Context API, Redux Toolkit, or Zustand.
- APIs and Data: Ensure your REST or GraphQL endpoints are mobile-friendly (e.g., handle offline data with WorkManager).
- UI/UX: Note web-specific styles (e.g., CSS) that need adaptation for mobile screens.
Action
- Document your app’s architecture and list components for reuse. Use tools like Bit to extract reusable UI components.
2. Set Up a New React Native Project
Using React Native CLI
- Initialize a new project:
npx @react-native-community/cli@latest init MobileApp - Navigate to the project:
cd MobileApp
Using Expo (Recommended for Simplicity)
- Create a project:
npx create-expo-app@latest MobileApp --template blank-typescript - Start the app:
npx expo start
- Hermes Compatibility: No extra configuration is needed in
app.jsonfor Expo 51+ as Hermes is enabled by default:"expo": {
"jsEngine": "hermes"
}
Why Expo?
Expo 51 simplifies native module integration and includes Hermes, reducing setup time. Dopebase offers Expo-compatible templates to jumpstart this step.
3. Migrate Reusable Code
Transfer Components
- Copy reusable React components (e.g.,
Button,Input) from your web app to thesrc/componentsfolder. - Update imports to use React Native’s core components (e.g., replace
divwithView,spanwithText). - Example:
// Web: src/components/Button.js
import React from 'react';
import './Button.css';
const Button = ({ children, onClick }) => (
<button className="btn" onClick={onClick}>{children}</button>
);
// Mobile: src/components/Button.tsx
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
const Button = ({ children, onClick }) => (
<TouchableOpacity style={styles.button} onPress={onClick} accessible={true}>
<Text style={styles.text}>{children}</Text>
</TouchableOpacity>
);
const styles = StyleSheet.create({
button: { padding: 10, backgroundColor: '#007AFF', minWidth: 48, minHeight: 48 }, // 48x48 touch target for accessibility
text: { color: '#fff', textAlign: 'center' },
});
export default Button;
Adapt State Management
- Context API: Migrate directly with minor adjustments for mobile lifecycle events.
- Redux Toolkit: Install
@reduxjs/toolkitandreact-redux:Configure a store and reuse reducers from your web app.npm install @reduxjs/toolkit react-redux - Zustand: Works out of the box with no platform-specific issues. Continue using your stores as-is if they’re not tightly coupled to DOM APIs. Example:
import create from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
export default useStore;
4. Handle Styling and Layout
Replace CSS with StyleSheet
- Convert web CSS to React Native’s
StyleSheet. Use flexbox for responsive layouts:import { StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
});
Use Tailwind CSS (Optional)
- Integrate
react-native-tailwindcssfor a web-like styling experience:npm install react-native-tailwindcss - Example:
import tw from 'react-native-tailwindcss';
const App = () => <View style={tw`flex-1 justify-center items-center bg-gray-100`}>Hello</View>;
Accessibility Note
Ensure touch targets are at least 48x48 dp for accessibility, as required by React Native guidelines. Adjust button styles accordingly (see example above).
5. Implement Navigation
Use React Navigation 7
- Install dependencies:
npm install @react-navigation/native @react-navigation/native-stack
npx expo install react-native-screens react-native-safe-area-context - Set up a stack navigator:
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
const App = () => (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
export default App;
Deep Linking (Optional)
If your web app uses routing, set up deep linking:
<NavigationContainer linking={linking}>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
const linking = {
prefixes: ['yourapp://'],
config: { screens: { Home: '' } },
};
6. Test and Optimize
Run on Emulators
- For Android:
npx react-native run-android - For iOS:
npx react-native run-ios
Optimize with Hermes
- Hermes is the standard engine in supported React Native projects. Verify the generated native build configuration when migrating an older app:
project.ext.react = [
enableHermes: true,
]
Debugging
- React Native CLI: Use React Native DevTools and native platform profilers for debugging:
npm install --save-dev @react-native-community/flipper - Expo: Use Expo DevTools during development and a privacy-reviewed observability service for release builds:
npm install @sentry/react-native
7. Deploy to App Stores
For React Native CLI
- Android: Create a signed APK/AAB:
cd android && ./gradlew bundleRelease - iOS: Archive in Xcode and submit via App Store Connect.
For Expo Managed Workflow
- Use EAS Build:
npx eas build --platform android
npx eas build --platform ios - Alternatively, with classic Expo build:
npx expo build:android
npx expo build:ios
Dopebase Templates
Dopebase provides pre-configured templates with CI/CD setups (e.g., Fastlane) to streamline deployment. Check instamobile.io for React Native options.
Current best practices
- Leverage TypeScript: Use TypeScript for type safety across web and mobile codebases.
- Optimize Images: Use
react-native-fast-imagefor efficient loading. Additionally:- Integrate
react-native-svgfor scalable vector graphics:npm install react-native-svg - Load images from CDNs like Cloudinary for dynamic content.
- Integrate
- Enable Dark Mode: Implement theming with
AppearanceAPI:import { useColorScheme } from 'react-native';
const App = () => {
const colorScheme = useColorScheme();
const theme = colorScheme === 'dark' ? darkStyles : lightStyles;
return <View style={theme.container} />;
}; - Platform-Specific Behaviors: Use
expo-deviceto detect device capabilities:npm install expo-deviceimport * as Device from 'expo-device';
if (Device.osName === 'iOS') { /* iOS-specific logic */ } - Consistent Layouts: Use
react-native-responsive-dimensionsfor adaptive designs:npm install react-native-responsive-dimensions
Conclusion
Migrating a web app to mobile with React Native is a strategic move to reach wider audiences with minimal rework. By reusing your React components, adopting modern tools like Hermes, React Navigation 7, and optimizing for accessibility and performance, you can launch a native app efficiently. For a head start, Dopebase offers production-ready templates at instamobile.io and instaflutter.com, tailored for React Native and Flutter. Follow us on X or Facebook for more migration tips and join our community to share your journey!
Hashtags
#Dopebase #MobileApps #ReactNative #WebToMobile #AppDevelopment #Expo #Hermes #TypeScript #ReactNavigation #Flutter #Tech2025
Additional Resources
- dopebase.com - Mobile app development resources and templates
- instamobile.io - Explore our production-ready React Native templates
- instaflutter.com - Check out our Flutter templates for cross-platform development
- iosapptemplates.com - Premium iOS app templates for quick development