Frontend Development 21 min read

Integrating react-native-web into a React Native Project: A Step‑by‑Step Guide

This article explains how to extend a React Native project with react-native-web, covering the motivation, required dependencies, project setup, webpack and Babel configuration, entry‑file creation, AppRegistry usage, component implementation, and JDReact’s practical extensions for seamless multi‑platform deployment.

JD Retail Technology
JD Retail Technology
JD Retail Technology
Integrating react-native-web into a React Native Project: A Step‑by‑Step Guide

React Native enables JavaScript developers to build native iOS and Android apps, but its original vision of "Write once, render anywhere" did not include the web. Facebook later introduced the concept of "Learn once, write anywhere" and open‑sourced react-native-web , which maps React Native components to web equivalents (e.g., View → div , Image → img ) without modifying existing code.

1. Project scaffolding

First, set up the development environment (macOS, iOS) and install required tools:

brew install node
# Watchman monitors file changes
brew install watchman
# Switch npm registry to Taobao
nrm use taobao

Create a new React Native project and install its dependencies:

react-native init rnweb
cd rnweb
npm install

Run the app on iOS to verify the native setup:

yarn ios
# or
yarn react-native run-ios

2. Adding react-native-web

Install the core libraries needed for the web target:

npm install react react-dom react-native-web

Create the web entry file index.web.js :

import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
AppRegistry.registerComponent(appName, () => App);
AppRegistry.runApplication(appName, { initialProps: {}, rootTag: document.getElementById('root') });

3. Webpack & Babel configuration

Install the build tools:

npm install webpack webpack-cli webpack-dev-server --save-dev
npm install babel-loader --save-dev

Configure webpack.config.js (development mode shown):

const path = require('path');
module.exports = {
  entry: './index.web.js',
  output: { filename: 'index.web.js', path: path.resolve(__dirname, 'build') },
  mode: 'development',
  module: { rules: [{ test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader' } }] },
  resolve: { alias: { 'react-native$': 'react-native-web' } },
  devServer: { contentBase: path.resolve(__dirname, 'build'), port: 3001 },
  plugins: [new (require('html-webpack-plugin'))({ template: path.join(__dirname, 'index.html') })]
};

Provide a simple HTML template ( index.html ) that contains a div#root placeholder for the React app.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,viewport-fit=cover">
  <title>React Native For Web</title>
</head>
<body>
  <div id="root">React Native For Web</div>
</body>
</html>

4. Development server

Start the live‑reloading server:

npm run dev   # defined as "webpack-dev-server" in package.json

The server serves the bundled files at http://localhost:3001 . If errors appear, ensure Babel is fully configured (see step 8).

5. Babel full‑stack

npm install @babel/core @babel/runtime @babel/preset-react @babel/preset-env @babel/preset-flow --save-dev

Update webpack.config.js to include the Babel loader (already shown in step 3).

6. AppRegistry deep dive

Both native and web entry points rely on AppRegistry . On the web, AppRegistry.registerComponent stores a runnable in an internal map, and AppRegistry.runApplication invokes renderApplication (which ultimately calls ReactDOM.render or hydrate ) to mount the component tree into the DOM.

// Simplified AppRegistry implementation
var runnables = {};
var AppRegistry = {
  registerComponent(appKey, componentProvider) {
    runnables[appKey] = {
      getApplication(appParameters) { return _getApplication(componentProvider, appParameters); },
      run(appParameters) { renderApplication(componentProvider, null, null, appParameters); }
    };
    return appKey;
  },
  runApplication(appKey, appParameters) { runnables[appKey].run(appParameters); }
};

7. Component implementation example (Text)

The Text component in react-native-web decides whether to render a span or div based on nesting, applies style handling, and forwards refs:

class Text extends React.Component {
  renderText(hasTextAncestor) {
    const { style, numberOfLines, selectable, onPress } = this.props;
    const component = hasTextAncestor ? 'span' : 'div';
    const supportedProps = { /* classList, dir, ref, style */ };
    return React.createElement(component, supportedProps);
  }
  render() {
    return (
{hasTextAncestor =>
          hasTextAncestor ? this.renderText(true) :
{this.renderText(false)}
}
);
  }
}
export default applyLayout(applyNativeMethods(Text));

8. JDReact practical extensions

JDReact builds on the open‑source React Native stack, adding custom plugins, a dedicated .web.js entry, and a scaffolding tool that generates a web folder with webpack and HTML templates. Its package.json distinguishes runtime dependencies from dev‑only web libraries, and provides scripts web‑init , web‑start , and web‑bundle to automate initialization, local development, and production bundling.

{
  "scripts": {
    "web-init": "node ./xxxx-web/cli.js init",
    "web-start": "node ./xxxx-web/cli.js start",
    "web-bundle": "rm -rf build-web && node ./xxxx-web/cli.js bundle"
  },
  "dependencies": {
    "react": "16.8.3",
    "react-native": "0.59.9"
  },
  "devDependencies": {
    "xxxx-web": "^2.0.2"
  }
}

Running npm run web-init creates a web directory with webpack.config.* files; npm run web-start launches the dev server; and npm run web-bundle produces a production build.

Conclusion

By following the steps above, a standard React Native project can be extended to support iOS, Android, and Web with minimal code changes. The process involves installing react-native-web , configuring webpack and Babel, creating a web entry point, and understanding the role of AppRegistry . JDReact further streamlines this workflow for large‑scale enterprise projects.

Cross-PlatformWebpackWeb DevelopmentReact Nativereact-native-web
JD Retail Technology
Written by

JD Retail Technology

Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.