So you are starting a new project. A beautiful, shiny, greenfield app with all the latest cool tech, with an objective in mind to conquer the industry. You have the mockups and MVP planned already, and the team waiting for your signal to deliver. You want to support all the major browsers and platforms. But your team does not scale as you expect your app to. React Native for Web is the solution.

React Native for Web is a project made by Nicolas Gallagher to solve the problem of building same app in multiple codebases to support multiple platforms when you do not have the resources to do so. It allows your code to be run in the browser and to be installed in the mobile devices as a native mobile app.

How?

When you are writing an React.JS app you have to write HTML markup and style it using CSS, styles in JavaScript or your favourite styles preprocessor like SASS or LESS. If you are using React Native for Web, it translates your HTML tags to be understandable by React Native, so your divs become View, your input tag is TextInput and so on.

Styles are handled differently. To be compatible with React Native you have to use styles in JavaScript. For some it may be a downside, for others it might be a benefit. I think you can easily justify it, by looking at the good sides of using it. When working in the IT industry, every solution we choose, comes with a tradeoffs we have to accept to build the successful project.

Getting started

To get started you will have to have a working React Native project.
If you do not have any, just simply create a new one by running:

react-native init YourProjectName

The command above will create an empty React Native project named YourProjectName.

You can verify if your app is working by running react-native run-ios (when you are on Mac) or react-native run-android (for Android). You should see the default React Native starter screen. Feel free to leave it as it is, or you can replace it by your custom code, if you want to see something more.

Install React and React Native for Web:

npm i react react-dom react-native-web --save

Then install Webpack and Babel to build your code for a web use:

npm i --save-dev babel-loader url-loader webpack webpack-dev-server

Configure Webpack

Create file webpack.config.js in the root of your application:


const path = require('path');
const webpack = require('webpack');

const appDirectory = __dirname;

const babelLoaderConfiguration = {
  test: /\.js$/,
  include: [
    path.resolve(appDirectory, 'index.web.js'),
    path.resolve(appDirectory, 'src'),
    path.resolve(appDirectory, 'node_modules/react-native-uncompiled')
  ],
  use: {
    loader: 'babel-loader',
    options: {
      cacheDirectory: true,
      plugins: ['react-native-web/babel', 'transform-runtime'],
      presets: ['react-native']
    }
  }
};

const imageLoaderConfiguration = {
  test: /\.(gif|jpe?g|png|svg)$/,
  use: {
    loader: 'url-loader',
    options: {
      name: '[name].[ext]'
    }
  }
};

module.exports = {
  entry: path.resolve(appDirectory, 'index.web.js'),
  output: {
    filename: 'bundle.web.js',
    path: path.resolve(appDirectory, 'dist')
  },
  module: {
    rules: [
      babelLoaderConfiguration,
      imageLoaderConfiguration
    ]
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
      __DEV__: process.env.NODE_ENV === 'production' || true
    })
  ],

  resolve: {
    // `.web.js`.
    extensions: [ '.web.js', '.js' ]
  }
}

Run webpack dev server:

./node_modules/.bin/webpack-dev-server -d --inline --hot --colors

Then open http://localhost:8080/ in your browser and you should see exactly the same looking app than in the iOS/Android simulator.

For more information please refer to React Native for Web and Webpack docs.

Enjoy!