import { Meta } from '@storybook/addon-docs/blocks';

<Meta title="Overview|Getting started" />

# Getting started

This guide will help you render components and applications with React Native
for Web.

If you're not familiar with setting up a new React web project, please refer to
the [React documentation](https://reactjs.org/).

## Install

```
npm install react react-dom react-native-web
```

Your application may need to polyfill `Promise`, `Object.assign`, `Array.from`,
and [`ResizeObserver`](https://github.com/que-etc/resize-observer-polyfill) as
necessary for your desired browser support.

## Recommended starter kits

### Expo

[Expo](https://expo.io) is a framework and a platform for universal React
applications. [Expo for Web](https://docs.expo.io/workflow/web/) uses React
Native for Web and provides dozens of additional cross-platform APIs.

```
npm install expo-cli --global
expo init my-app
cd my-app
expo start
```

### Create React App

[Create React App](https://github.com/facebook/create-react-app) is a basic way
to setup a simple, web-only React app with built-in support for aliasing
`react-native-web` to `react-native`. However, it's generally recommended that
you use Expo.

```
npx create-react-app my-app
cd my-app
npm install react-native-web
npm start
```

## Standalone configurations

### Configuring a module bundler

If you have a custom setup, you may choose to configure your module bundler to
alias the package to `react-native`.

For example, modify your [webpack](https://github.com/webpack/webpack)
configuration as follows:

```js
// webpack.config.js
module.exports = {
  // ...the rest of your config

  resolve: {
    alias: {
      'react-native$': 'react-native-web'
    }
  }
}
```

### Configuring Babel

[Babel](https://babeljs.io/) supports module aliasing using
[babel-plugin-module-resolver](https://www.npmjs.com/package/babel-plugin-module-resolver)

```
{
  "plugins": [
    ["module-resolver", {
      "alias": {
        "^react-native$": "react-native-web"
      }
    }]
  ]
}
```

### Configuring Jest

[Jest](https://facebook.github.io/jest/) can be configured using the provided
preset. This will map `react-native` to `react-native-web` and provide
appropriate mocks:

```
{
  "preset": "react-native-web"
}
```

Please refer to the Jest documentation for more information.

### Configuring Flow

[Flow](https://flow.org) can be configured to understand the aliased module:

```
[options]
module.name_mapper='^react-native$' -> 'react-native-web'
```

You may also need to include a custom libdef
([example](https://gist.github.com/paularmstrong/f60b40d16fc83e1e8e532d483336f9bb))
in your config.

### Configuring Node.js

Node.js can alias `react-native` to `react-native-web` using
[`module-alias`](https://www.npmjs.com/package/module-alias). This is useful if
you want to pre-render the app (e.g., server-side rendering or build-time
rendering).

```js
// Install the `module-alias` package as a dependency first
const moduleAlias = require("module-alias");
moduleAlias.addAliases({
  "react-native": require.resolve("react-native-web"),
});
moduleAlias();
```

## Other notes

### Safari flexbox performance

Safari prior to version 10.1 can suffer from extremely [poor flexbox
performance](https://bugs.webkit.org/show_bug.cgi?id=150445). The recommended
way to work around this issue (as used on mobile.twitter.com) is to set
`display:block` on Views in your element hierarchy that you know don't need
flexbox layout.
