React Native & React Native Web, one code base for iOS, Android and web.

Conrad Johnston
5 min readJul 15, 2019

--

Write once run anywhere

It’s Earth and Mars and a City, three things, like iOS, Android and the Web. Images really make an article according to the “publish” screen in Medium.com

The once marketing slogan for Java is now the holy grail for mobile development teams across the globe. One code base deployable to iOS, Android and web. As of 2019 React Native/React Native Web is the closest we’ve ever been. This article takes you through using React Native/React Native Web to build News-a-tron 3000 a simple news reader.

The relationship between React Native, and React Native Web

React Native is a set of React components that are also implemented for iOS and Android as bespoke native widgets. This is a step change from a webview approach to building hybrid apps. The native components mean no janky UI issues, weird web-isms creeping into interactions, and generally a nicer experience. Accessibility attributes are supported.

In a strange full-circle moment, we take the mantra “mobile first” literally, building using React Native for handsets, and then using React Native Web to bridge back to a browser environment.

There are some compromises, which are mainly around being limited to using the components that are available for all three platforms, but as this article demonstraits, there’s enough out-of-the-box to get a decent class of apps into production.

Yarn or NPM, Typescript or Vanilla JS

This guide uses Yarn and Typescript because that’s how I roll. If you prefer npm and vanilla Javascript, live your best life and substitute commands were appropriate, the whole thing will still work great for you.

Simulator vs Emulator

Apple calls it’s iOS simulator a simulator because it is just that, a simulation of an iOS operating system. Android, on the other hand, runs a complete VM, and so calls their technology an Emulator. In this article I’ll be using simulator/emulator as the group noun for these programmes.

Getting Started

Because we are targeting iOS you will need a Mac; Apple are relentless in their demands that developers use their kit. On said Mac you’ll need have the following software installed:

  1. Android Studio
  2. Xcode
  3. yarn

Expo

Expo is a kinder version of React Native, which contains everything you need, under package management, to run iOS and Android apps. You are welcome to use React Native directly, but there will be more plumbing involved, trust me, Expo is your friend.

If you later decide you want more control over your project you can eject Expo and your project will become a self-managed ExpoKit/React Native situation. So choosing Expo now doesn’t commit you to it for ever and ever.

With Expo tools, services, and React Native, you can build, deploy, and quickly iterate on native iOS and Android apps from the same JavaScript codebase. (from the Expo home page)

yarn global add expo-cli

Creating the project

This interactive command will create a new Expo project.

expo init NewsATron3000

Following the onscreen prompts, set the following parameters:

Template: Blank (Typescript)
name: News-a-Tron 3000
slug: NewsATron3000
Yarn installs dependencies? Yes

That’s all there is too it, now, if you’re like me you’ll want to see it running right away, and you’re in luck, there are scripts to launch your first React Native app.

Launch in device simulators/emulators

yarn start

This will launch a command line tool (which this article will focus on), and a glorious web interface (which you can explore without guidance).

This technology is under development, so if it doesn’t work first try, restart the simulator/emulator, enable some permission or other, Google the error message. This is when you really want to lean into your developer faux-C-D and hammer away until you get the app running.

From the terminal you can use the following keyboard shortcut commands to get your app into a device simulator/emulator.

i for iOS, launches the iOS simulator, installs the code, enables hot loading and shows you the welcome screen.

a for Android, at the time of writing the Android emulator does not launch automatically. To get the emulator up and running:

  1. Launch Android Studio
  2. Configure > AVD Manager
  3. Create Virtual Device…
  4. Follow the onscreen prompts to create an emulator image
  5. In the terminal, get a list of emulator device names ~/Library/Android/Sdk/tools/emulator -list-avds
  6. ~/Library/Android/Sdk/tools/emulator -avd <name of device>

Now that the Android emulator is running you can hit a and see the app be deployed to the emulator.

React Native Web

This section owns a debt of gratitude to Jonny Kalamby, author of Your First Hybrid App in Minutes — React Native on the Web.

To run React Native code in React Native Web, you need a few more packages (of course you do, this is JS development after all).

yarn add react-scripts\
react-dom\
@types/react-dom\
react-native-web\
react-art\
react-router-native\
react-router-dom

Harmonizing entry points

Expo uses App.tsx as the entry point, but React Native Web uses src/index.tsx. Happily, a bit of a file reshuffle means we can have both entry points point, ultimately, to the same codebase.

What we are going to do is move the generated App.js into src/ because React Native Web chucks a tantrum about any files above src/ in the hierarchy. The original App.js will point to scr/App.tsx as will src/index.js and all will be well in the world.

mkdir src
mv App.tsx src/
emacs App.tsx # emacs or vi, whatever rocks your world

Paste in the following to the newly recreated Apps.tsx

import React from 'react'
import App from './src/App'
export default () => {
return <App />
}

emacs src/index.tsx

Again, paste the following into the newly created file.

import React from 'react';
import ReactDom from 'react-dom';
import App from './App';
ReactDom.render(
<App />,
document.getElementById("root")
);

Create an HTML harness

The last bit of file creation is the HTML harness that React Native Web will run inside.

mkdir public
emacs public/index.html

Then paste the following in the newly created file:

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>News-a-tron 3000</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

Starting React Native Web

Now that the code is set up, a couple commands need to be added to package.json, there are:

"scripts": {
/* There should be some script definitions here already, just append these two at the end */
"start-web": "react-scripts start",
"build-web": "react-scripts build"
},

Now you can run

yarn start web

And a browser will open containing your app. Magic.

--

--