React Native for Web
React Native for Web is a library that enables developers to run React Native components and APIs directly on the web using React DOM. It aims to maximize code reuse between native mobile and web platforms, providing a unified API surface that abstracts away platform-specific implementation details. The current stable version is 0.21.2, with minor releases occurring relatively frequently, indicating active development. Key differentiators include its ability to directly interpret React Native's styling system (Yoga layout), accessibility APIs, and core components for web rendering, thereby allowing a single codebase to target multiple platforms, distinct from approaches that require separate web components or extensive platform-specific logic.
Common errors
-
Error: Cannot find module 'react-native'
cause The build system (Webpack/Babel) is not configured to alias 'react-native' to 'react-native-web' for the web environment.fixAdd `babel-plugin-module-resolver` or a Webpack alias to your build configuration to map `react-native` to `react-native-web` for web builds. -
Invariant Violation: findNodeHandle is not supported on web.
cause Attempting to use `findNodeHandle` in a `react-native-web` application, which was removed with React 19 support in v0.20.0.fixRemove all calls to `findNodeHandle` from your codebase targeting the web. Consider using `ref` for direct DOM access or alternative web-specific APIs. -
TypeError: (0 , react_dom__WEBPACK_IMPORTED_MODULE_2__.createRoot) is not a function
cause This typically occurs when `react-dom` is not correctly set up for React 18's `createRoot` API, or there's a version mismatch.fixEnsure `react-dom` peer dependency is `^18.0.0 || ^19.0.0` and that your application entry point uses `ReactDOM.createRoot` instead of `ReactDOM.render` for React 18 and newer. -
ReferenceError: document is not defined
cause This error often happens during server-side rendering (SSR) when client-side APIs (like `document`) are accessed in a Node.js environment.fixImplement proper checks (e.g., `typeof document !== 'undefined'`) around client-specific code or use a library for SSR that provides a simulated DOM environment.
Warnings
- breaking With React 19 support introduced in v0.20.0, the `findNodeHandle` API is no longer supported on the web platform.
- breaking Version 0.18.0 significantly reduced browser support, dropping compatibility for IE and legacy Android browsers. Supported browsers are Safari 10.1+, and Edge (Chromium).
- breaking Since v0.18.0, styles are inserted on module evaluation rather than component rendering. This change affects server-side rendering, where style sheets now include styles from all evaluated modules, not just those from the initial render.
- breaking The `I18nManager` API was updated in v0.15.0. Properties like `isRTL` and `doLeftAndRightSwapInRTL` are no longer direct properties and must be accessed via the `getConstants()` method.
- gotcha Correct Babel/Webpack configuration is crucial for 'react-native' imports to resolve to 'react-native-web'. Without proper aliasing, web builds will fail.
Install
-
npm install react-native-web -
yarn add react-native-web -
pnpm add react-native-web
Imports
- { View, Text, StyleSheet }
import { View, Text, StyleSheet } from 'react-native-web';import { View, Text, StyleSheet } from 'react-native'; - AppRegistry
import { AppRegistry } from 'react-native-web';import { AppRegistry } from 'react-native'; - Platform
import { Platform } from 'react-native';
Quickstart
import React from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
class App extends React.Component {
render() {
return (
<View style={styles.box}>
<Text style={styles.text}>Hello, world!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
box: { padding: 10 },
text: { fontWeight: 'bold' }
});
AppRegistry.registerComponent('App', () => App);
AppRegistry.runApplication('App', { rootTag: document.getElementById('react-root') });