Menu Search
Jump to the content X X
Smashing Conf New York

You know, we use ad-blockers as well. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. our upcoming SmashingConf New York, dedicated to smart front-end techniques and design patterns.

A Glimpse Into The Future With React Native For Web

One of the hardest decisions to make when starting a new app is which platforms to target. A mobile app gives you more control and better performance but isn’t as universal as the web. If you’re making a mobile app, can you afford to support both iOS and Android? What about trying to build a mobile app and a responsive web app? Ultimately, the best experience for your customers is for your app to work everywhere, but the development and maintenance costs of that can be prohibitive.

We have already seen how1 React Native can help you make iOS and Android apps with a shared code base, without sacrifices in quality. But what about the web? This is exactly the problem the React Native for Web352 project is trying to solve. Instead of forcing you to maintain two separate code bases for your mobile and web apps, or making a hybrid app, with all its compromises3.

Further Reading on SmashingMag: Link

React Native for Web is intended to let you write a single app that runs in a browser using standard web technologies, or on iOS and Android as a real native mobile app. While I don’t think the project is ready for production use yet, its potential success could mark a massive change in how large multi-platform applications are built. Let’s jump in!

How It Works Link

You might be thinking, “Wait! doesn’t React already work on the web?” You wouldn’t be wrong. Unfortunately, traditional React and React Native build on a different set of primitives. React uses <div>, <p> and <input>, whereas React Native uses <View>, <Text> and <TextInput>. There are good historical reasons for this, since the building blocks of a web page and of a mobile app are quite different. Nonetheless, it would be great if we could use a single set of shared components.

React Native for Web’s solution is to provide browser-compatible implementations of React Native’s components — meaning, for example, that the <View> of React Native has a DOM-based version that knows how to render to a <div>. While not every React Native component is supported, enough of them are that you could (hopefully) share the majority of your code base.

In addition to the components themselves, styles for React and React Native are written differently. With React, most people use plain CSS or a preprocessor such as Sass8. But in React Native, all styles are written in JavaScript, because there is no DOM and no selectors. With React Native for Web, styles are written just like they would be for React Native, rather than with CSS. This has the benefit of allowing you to write a single set of styles, which will work on both native mobile and the web.

We’ll take a deeper look later at how these ideas work in practice and at how much code is actually reusable. First, let’s get a sample app going.

Starting A New React Native Project Link

To get started, we will need to set up our project. At first, this will just be a regular React Native app, and then we’ll add React Native for Web. If you are following along, you’ll need to complete React Native’s “Getting Started369” guide before heading into the next section.

Once you’ve got React Native installed, you can run the following command from your terminal:

react-native init ReactNativeWeb

This will make a new React Native project named ReactNativeWeb. After it has finished installing, you can cd ReactNativeWeb, and then react-native run-ios or react-native run-android. If everything has gone correctly, you should see a friendly welcome message on your iOS or Android simulator or device.

React Native iOS welcome screen10
React Native iOS welcome screen (View large version11)
React Native Android welcome screen12
React Native Android welcome screen (View large version13)

Notice that React Native has created two JavaScript files in our project’s directory: index.android.js and index.ios.js. You can edit any of the styles or logic in these files and see those changes update in the running app. As you can probably guess, the .android.js file is for Android, and the .ios.js file is for iOS. Fortunately, separate files are only needed when you want multiple versions of a given file per platform. Most of the time, you’ll have a single file per component.

Managing Dependencies Link

Before we can get our app running in a web browser, we’ll need to get a bit of package installation out of the way. First, run the following to install both the react-native-web package and the official React web packages.

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

(You might see some errors about peer dependencies from this command. You should be safe to ignore them, because they didn’t cause me any problems. If newer versions of any of these packages are out when you run the commands, though, you might need to adjust the installed versions.)

At this point, your package.json file should look something like this:

{
  "name": "ReactNativeWeb",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "react": "15.1.0",
    "react-dom": "15.1.0",
    "react-native": "0.28.0",
    "react-native-web": "0.0.25"
  }
}

While we have what seems to be everything required for our React Native app to run in a web browser, we must take a brief detour to consider the realities of web development. React Native’s packager compiles your ECMAScript 6 code to something that a phone’s JavaScript engine can understand, but it won’t help us in the browser. If we tried to run our app in a web browser right now, it would quickly fail due to syntax errors.

To solve this problem, we will use Babel14 and webpack15. Babel will compile our ECMAScript 6 code into browser-compatible ECMAScript 5, and webpack will bundle the compiled JavaScript, as well as just generally make development faster. (There are other options for this. If you prefer another compiler or bundler, feel free to use it instead.)

Here are the installation commands to run:

npm i webpack babel-loader babel-preset-react babel-preset-es2015 --save
npm i webpack-dev-server --save-dev

Here, babel-loader and webpack-dev-server will be used to bundle and serve our JavaScript, while babel-preset-react and babel-preset-es2015 tell Babel which plugins we need to compile our code.

Here is what your package.json file should look like now:

{
  "name": "ReactNativeWeb",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "babel-loader": "6.2.4",
    "babel-preset-es2015": "6.9.0",
    "babel-preset-react": "6.5.0",
    "react": "15.1.0",
    "react-dom": "15.1.0",
    "react-native": "0.28.0",
    "react-native-web": "0.0.25",
    "webpack": "1.13.1"
  },
  "devDependencies": {
    "webpack-dev-server": "1.14.1"
  }
}

Configuring Link

Those are all of the packages we will need. But more setup is required before our app will work in a browser.

webpack.config.js Link

First, we’ll make a webpack config file. This file tells webpack how to build, bundle and serve our compiled code. In addition, we are going to use the alias property to automatically replace imports on react-native with react-native-web. This file should be placed in your project’s root.

const webpack = require('webpack');

module.exports = {
  entry: {
    main: './index.web.js',
  },
  module: {
    loaders: [
      {
        test: /\.js?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'react'],
        },
      },
    ],
  },
  resolve: {
    alias: {
      'react-native': 'react-native-web',
    },
  },
};

index.html Link

Now, we need to create an HTML file for our app to run in. This will be pretty simple because it will just be a skeleton to attach our React app to.

<!DOCTYPE html>
<html>
<head>
  <title>React Native Web</title>
  <meta charSet="utf-8" />
  <meta content="initial-scale=1,width=device-width" name="viewport" />
</head>
<body>
  <div id="react-app"></div>
  <script type="text/javascript" src="/bundle.js"></script>
</body>
</html>

index.web.js Link

Finally, we must make an index JavaScript file for the web. The contents of this file can be the same as index.ios.js or index.android.js, but with one additional line to attach to the DOM. The div with the ID react-app from our HTML file must be selected and then used in the call to AppRegister.runApplication.

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

class ReactNativeWeb extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.web.js
        </Text>
        <Text style={styles.instructions}>
          Press Cmd+R to reload
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('ReactNativeWeb', () => ReactNativeWeb);
AppRegistry.runApplication('ReactNativeWeb', { rootTag: document.getElementById('react-app') });

Now, just run ./node_modules/.bin/webpack-dev-server --inline to start webpack, and open your browser to http://localhost:8080/16. Fingers crossed, you will see a familiar welcome message but in the browser!

React Native web welcome screen17
React Native web welcome screen (View large version18)

With all of that setup complete, we are ready to start tinkering!

Experimenting With The Code Link

Create a FriendsList.js Component Link

Let’s start by making a friends list. This will be a good simple stress test of React Native for Web, because we need to use a few different components for it: <Image>, <Text>, <View> and <ListView>.

import React, { Component } from 'react';
import {
  Image,
  ListView,
  StyleSheet,
  Text,
  View,
} from 'react-native';

const styles = StyleSheet.create({
  list: {
    marginTop: 20,
  },
  friend: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'flex-start',
  },
  avatar: {
    margin: 10,
    width: 50,
    height: 50,
    borderRadius: 25,
  },
  name: {
    fontSize: 18,
    color: '#000',
  }
});

export default class FriendsList extends Component {
  constructor(props) {
    super(props);
    const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
    this.state = {
      ds: ds.cloneWithRows(props.friends),
    };
  }

  render() {
    return (
      <ListView
        dataSource={this.state.ds}
        style={styles.list}
        renderRow={(friend) =>
          <View style={styles.friend}>
            <Image style={styles.avatar} source={{ uri: friend.avatarUrl }} />
            <Text style={styles.name}>{friend.firstName} {friend.lastName}</Text>
          </View>
        } />
    );
  }
}

We’ll need to edit our index files, too, so that a friends array gets passed in as a prop.

import FriendsList from './FriendsList';
import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  View
} from 'react-native';

const friends = [
  {
    id: 1,
    firstName: 'Jane',
    lastName: 'Miller',
    avatarUrl: 'https://placehold.it/100x100',
  },
  {
    id: 2,
    firstName: 'Kate',
    lastName: 'Smith',
    avatarUrl: 'https://placehold.it/100x100',
  },
  {
    id: 3,
    firstName: 'Kevin',
    lastName: 'Yang',
    avatarUrl: 'https://placehold.it/100x100',
  },
];

class ReactNativeWeb extends Component {
  render() {
    return <FriendsList friends={friends} />;
  }
}

AppRegistry.registerComponent('ReactNativeWeb', () => ReactNativeWeb);

Upon running it in iOS or Android, you should see something like this:

React Native iOS friends list19
React Native iOS friends list (View large version20)

Looks good so far. Let’s see the web version:

React Native web friends list21
React Native web friends list. (View large version22)

Uh oh! Turns out there isn’t any web support yet for ListView’s DataSource, effectively making ListView completely unusable.

Friend.js Link

We can work around this lack of support for now. Let’s make a Friend component for the individual rows, but have a FriendsList component per platform. This will separate out the shared code that works everywhere but allow us to customize each platform where we need to.

import React, { Component } from 'react';
import {
  Image,
  StyleSheet,
  Text,
  View,
} from 'react-native';

const styles = StyleSheet.create({
  friend: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'flex-start',
  },
  avatar: {
    margin: 10,
    width: 50,
    height: 50,
    borderRadius: 25,
  },
  name: {
    fontSize: 18,
    color: '#000',
  }
});

export default class Friend extends Component {
  render() {
    return (
      <View style={styles.friend}>
        <Image style={styles.avatar} source={{ uri: this.props.avatarUrl }} />
        <Text style={styles.name}>{this.props.firstName} {this.props.lastName}</Text>
      </View>
    );
  }
}

FriendsList.ios.js Link

import Friend from './Friend';
import React, { Component } from 'react';
import {
  Image,
  ListView,
  StyleSheet,
  Text,
  View,
} from 'react-native';

const styles = StyleSheet.create({
  list: {
    marginTop: 20,
  },
});

export default class FriendsList extends Component {
  constructor(props) {
    super(props);
    const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
    this.state = {
      ds: ds.cloneWithRows(props.friends),
    };
  }

  render() {
    return (
      <ListView
        dataSource={this.state.ds}
        style={styles.list}
        renderRow={(friend) =>
          <Friend
            key={friend.id}
            avatarUrl={friend.avatarUrl}
            firstName={friend.firstName}
            lastName={friend.lastName} />
        } />
    );
  }
}

On iOS, our ListView usage code is unchanged. (I’m leaving out the Android code example here and for the rest of the article, for brevity. The Android and iOS code can be the same for the rest of the code samples.)

FriendsList.web.js Link

import Friend from './Friend';
import React, { Component } from 'react';
import {
  Image,
  Text,
  View,
} from 'react-native';

export default class FriendsList extends Component {
  render() {
    return (
      <View>
        {this.props.friends.map(friend =>
          <Friend
            key={friend.id}
            avatarUrl={friend.avatarUrl}
            firstName={friend.firstName}
            lastName={friend.lastName} />
        )}
      </View>
    );
  }
}

Now, for the web, we use the map function to render each Friend, similar to traditional React.

React Native friends list on the web, now working23
React Native friends list on the web, now working (View large version24)

Much better. At this point, hearing that ListView requires workarounds might be enough to make you think that React Native for Web isn’t ready for production use. I am inclined to agree, particularly since lists constitute a large percentage of many applications. How much it matters will vary depending on the project, though. On the bright side, all of our other React Native code so far has been completely reusable. In any case, I am still interested in exploring it further, because there is still much potential in the ideas on display here. Let’s continue with our sample app.

Instead of hardcoding a handful of list items, we can use JSON Generator25 to create a long list for us to work with. If you haven’t used it before, JSON Generator is a great tool for creating dummy and development data. Here is the structure I have defined, which adds a few fields on top of what we already have.

[
  '{{repeat(200)}}',
  {
    id: '{{guid()}}',
    firstName: '{{firstName()}}',
    lastName: '{{surname()}}',
    avatarUrl: 'https://placehold.it/100x100',
    isOnline: '{{bool()}}',
    company: '{{company()}}',
    email: '{{email()}}'
  }
]

And here is a snippet of some of the generated data:

[
  {
    "id": "c5368bbe-adfb-424f-ade3-9d783befa2b6",
    "firstName": "Hahn",
    "lastName": "Rojas",
    "avatarUrl": "https://placehold.it/100x100",
    "isOnline": true,
    "company": "Orbixtar",
    "email": "hahnrojas@orbixtar.com"
  },
  {
    "id": "15ef2834-3ba5-4621-abf1-d771d39c2dd6",
    "firstName": "Helen",
    "lastName": "Stout",
    "avatarUrl": "https://placehold.it/100x100",
    "isOnline": true,
    "company": "Ebidco",
    "email": "helenstout@ebidco.com"
  },
  {
    "id": "1ef05de1-fd8e-41ae-85ac-620b6d716b62",
    "firstName": "Floyd",
    "lastName": "Mcpherson",
    "avatarUrl": "https://placehold.it/100x100",
    "isOnline": false,
    "company": "Ecraze",
    "email": "floydmcpherson@ecraze.com"
  },
  …
]

To use it, just take your generated JSON and replace our friends array declaration from before. Of course, you can move that data into its own file if you’d like, so that your code files aren’t cluttered with data. In a real application, we would get that data from an API server.

Friend.js Link

Next, we can add these new fields to the Friend component.

…
render() {
  return (
    <View style={styles.friend}>
      <Image
        style={[styles.avatar, { borderColor: this.props.isOnline ? '#9d9' : '#d99' }]}
        source={{ uri: this.props.avatarUrl }} />

      <View>
        <Text style={styles.name}>{this.props.firstName} {this.props.lastName}</Text>
        <Text style={styles.company}>{this.props.company}</Text>
        <Text style={styles.email}>{this.props.email}</Text>
      </View>
    </View>
  );
}
…

FriendsList.js Link

Next, add them as props in each platform’s FriendsList.

…
<Friend
  key={friend.id}
  avatarUrl={friend.avatarUrl}
  firstName={friend.firstName}
  lastName={friend.lastName}
  isOnline={friend.isOnline}
  company={friend.company}
  email={friend.email} />
…
React Native long friends list for iOS26
React Native’s long friends list for iOS (View large version27)
React Native long friend list web28
React Native’s long friends list for the web (View large version29)

So far so good. It is encouraging to see that the core components seem to work well.

Friend.js Link

Next, we can add an animation with a transformation to see how well those work. Let’s make it so that when you tap a row, it animates left and right before returning to its initial position. We will need to add imports for Animated and TouchableOpacity, and wire up the animation and press handler.

import {
  Animated,
  TouchableOpacity,
  …
} from 'react-native';

…

export default class Friend extends Component {
  constructor(props) {
    super(props);
    this.state = {
      translateValue: new Animated.Value(0),
    };
  }

  animate() {
    Animated.sequence([
      Animated.timing(this.state.translateValue, {
        toValue: 50,
        duration: 200,
      }),
      Animated.timing(this.state.translateValue, {
        toValue: -50,
        duration: 200,
      }),
      Animated.timing(this.state.translateValue, {
        toValue: 0,
        duration: 200,
      })
    ]).start();
  }

  render() {
    return (
      <TouchableOpacity onPress={() => this.animate()} style={[styles.friend, { transform: [{ translateX: this.state.translateValue }]}]}>
        <Image
          style={[styles.avatar, { borderColor: this.props.isOnline ? '#9d9' : '#d99' }]}
          source={{ uri: this.props.avatarUrl }} />

        <View>
          <Text style={styles.name}>{this.props.firstName} {this.props.lastName}</Text>
          <Text style={styles.company}>{this.props.company}</Text>
          <Text style={styles.email}>{this.props.email}</Text>
        </View>
      </TouchableOpacity>
    );
  }
}

Looks good on mobile.

React Native iOS animation30
React Native iOS animation (View large version31)

What about the web?

React Native web animation32
React Native web animation (View large version33)

No luck. Our TouchableOpacity throws an error when pressed. Apparently, this will be fixed34 in the next release and is only present for our particular combination of versions. Attempting to run the animation without using TouchableOpacity causes the same error, too.

I am going to stop here, but if you want to continue on your own, here is a list of topics you could research next:

  • How well do the remaining React Native components and APIs work? We’ve seen that some definitely don’t work, but we don’t yet have a comprehensive list of support.
  • You could explore more extensive styling work, including media queries.
  • React Native for Web supports server rendering. This could be particularly cool because, if it works, it would mean that you could have a single code base driving native mobile applications and a responsive web app that is SEO-optimized.

Conclusion Link

As you can tell, React Native for Web is definitely not ready for production. There are too many unsupported components, even in our small demo app, for me to feel confident about using it in a real project. The most encouraging thing to me, though, is that the pieces that do work seem to completely work, and the parts that don’t, fail entirely. I find that much preferable to the entire thing just kind of working. At the moment, it seems like the project just needs more time to build support. If everything was only 50% functional, I would view that as a sign that the approach is fundamentally broken.

Despite the problems, I still think this is a very exciting project and worth keeping an eye on.

Resources Link

(da, ml, al)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2016/04/consider-react-native-mobile-app/
  2. 2 https://github.com/necolas/react-native-web
  3. 3 http://www.apptentive.com/blog/5-points-to-consider-before-making-a-hybrid-mobile-app/
  4. 4 https://www.smashingmagazine.com/2016/04/consider-react-native-mobile-app/
  5. 5 https://www.smashingmagazine.com/2016/09/how-to-scale-react-applications/
  6. 6 https://www.smashingmagazine.com/2016/04/the-beauty-of-react-native-building-your-first-ios-app-with-javascript-part-1/
  7. 7 https://www.smashingmagazine.com/2017/01/internationalizing-react-apps/
  8. 8 http://sass-lang.com/
  9. 9 https://facebook.github.io/react-native/docs/getting-started.html
  10. 10 https://www.smashingmagazine.com/wp-content/uploads/2016/07/01-react-native-welcome-ios-opt.png
  11. 11 https://www.smashingmagazine.com/wp-content/uploads/2016/07/01-react-native-welcome-ios-opt.png
  12. 12 https://www.smashingmagazine.com/wp-content/uploads/2016/07/02-react-native-welcome-android-opt.png
  13. 13 https://www.smashingmagazine.com/wp-content/uploads/2016/07/02-react-native-welcome-android-opt.png
  14. 14 https://babeljs.io/
  15. 15 https://webpack.github.io/
  16. 16 http://localhost:8080/
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2016/07/03-react-native-welcome-web-opt.png
  18. 18 https://www.smashingmagazine.com/wp-content/uploads/2016/07/03-react-native-welcome-web-opt.png
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2016/07/04-react-native-friends-ios-opt.png
  20. 20 https://www.smashingmagazine.com/wp-content/uploads/2016/07/04-react-native-friends-ios-opt.png
  21. 21 https://www.smashingmagazine.com/wp-content/uploads/2016/07/05-react-native-friends-web-opt.png
  22. 22 https://www.smashingmagazine.com/wp-content/uploads/2016/07/05-react-native-friends-web-opt.png
  23. 23 https://www.smashingmagazine.com/wp-content/uploads/2016/07/06-react-native-friends-web-2-opt.png
  24. 24 https://www.smashingmagazine.com/wp-content/uploads/2016/07/06-react-native-friends-web-2-opt.png
  25. 25 http://www.json-generator.com/
  26. 26 https://www.smashingmagazine.com/wp-content/uploads/2016/07/07-react-native-friends-2-ios-opt.png
  27. 27 https://www.smashingmagazine.com/wp-content/uploads/2016/07/07-react-native-friends-2-ios-opt.png
  28. 28 https://www.smashingmagazine.com/wp-content/uploads/2016/07/08-react-native-friends-2-web-opt.png
  29. 29 https://www.smashingmagazine.com/wp-content/uploads/2016/07/08-react-native-friends-2-web-opt.png
  30. 30 https://www.smashingmagazine.com/wp-content/uploads/2016/07/09-react-native-ios-animation-opt.gif
  31. 31 https://www.smashingmagazine.com/wp-content/uploads/2016/07/09-react-native-ios-animation-opt.gif
  32. 32 https://www.smashingmagazine.com/wp-content/uploads/2016/07/10-react-native-web-animation-opt.png
  33. 33 https://www.smashingmagazine.com/wp-content/uploads/2016/07/10-react-native-web-animation-opt.png
  34. 34 https://github.com/necolas/react-native-web/issues/150
  35. 35 https://github.com/necolas/react-native-web
  36. 36 https://facebook.github.io/react-native/docs/getting-started.html

↑ Back to top Tweet itShare on Facebook

Clayton Anderson is a partner at The BHW Group in Austin, TX. Outside of work, he is a total music nerd, and enjoys reading, Belgian beers, and playing board games.

  1. 1

    Is React Native for the web actually progressive web apps?
    thanks

    0
    • 2

      No, it runs totally differently, both the hardware utilized, and the software it runs.

      0
  2. 3

    I have the same question as Dim. Hope to hear soon from you.

    0
  3. 4

    Ah. The shared code base. The Holy Grail of dev since the beginning of time. If only users cared about such things.

    1
  4. 5

    Paul d'Aoust

    August 8, 2016 4:59 pm

    Wait, so first we have a framework for building web apps, and then it got retooled so you can build native apps, and now that has been retooled for web apps?

    (ノಥ益ಥ)ノ ┻━┻

    Someone stop this industry for a moment; I’m getting motion sickness. I want to get off, go home, see my family, and grow a few veggies.

    (Nothing of actual value to contribute to the discussion, BTW. Feel free to downvote.)

    77
    • 6

      Alex Dimitrov

      August 8, 2016 5:54 pm

      Sorry, but I must upvote it. It’s really going too far and someone needs to find an actual proper way of doing all of this. I am not very much into backend or anything, but simply seeing how styling is added there makes me sick. I bet you can see 125084 other issues with this that I can’t.

      1
      • 7

        James Gillmore

        August 12, 2016 5:44 am

        I disagree, this is the essence of how our stack of technologies evolve. I.e. with a superior interfaces operating as facades on other parts of the stack until the underlying technologies catch up.

        Styling without classes and CSS is jarring when first coming to React Native, but that’s a React Native problem, not anything unique to React Native Web. And that’s if you consider it a problem. I don’t and have loved using it and am over CSS. I much prefer the explicitness and even more so the isolation. It’s a different way that will take getting used to coming from standard CSS/LESS/SASS. But it’s a solid way, one worth taking a good look at.

        Anyway, this project has a ton of potential, given how groundbreaking and effective React Native is. It might very well be the missing piece linking native and web development, similar to what Famo.us was trying to achieve.

        7
    • 8

      Paul Francis

      August 8, 2016 5:55 pm

      Haha! I can definitely agree with the feeling. I guess my main defense of this approach is that RN is already cross-platform and it seems to be working quite well. Obviously going from supporting 2 platforms to 3, is a pretty big leap, but it would be awesome if it works out. It would be like hybrid, but reversed, and not terrible.

      5
    • 9

      I couldn’t agree more actually with this comment. What about the 30,000 files you pull after an npm install, to include observing fun JS files such as CSS-What and Surfboard.js. It’s like a rats nest of JS out there and one needs to seriously focus just to get some coding done, especially if you have self-diagnosed adult ADD like me.

      But no, seriously, React and Flux– I mean Redux– I mean RiotJS are awesome and I’m sure things will come together more in the future. The paradigm shift is that JavaScript is king.

      0
      • 10

        Headache.js anyone? It’s only a matter of time before someone does it ;) Here’s a visual:

        npm install -g headachejs-cli

        1
    • 11
  5. 12

    Yeah, no. I am not convinced. You still have to write specialized code for every platform, using non-standard HTML markup makes the markup hard to read and maintain unless you are experienced with React Native, mixing JavaScript, markup and styling into one mess? Have fun convincing all your backenders, frontenders, and designers that its a good idea, and also convincing your boss that everyone has to learn React Native before they can even start the project.

    8
    • 13

      James Gillmore

      August 12, 2016 5:46 am

      For hard core react native projects, this is a blessing. I.e. “react native first” projects. And many projects are starting out in React Native. My latest one has. I’m currently making sure the codebase works in Android, and then I’m going to try to use React Native Web to make a minimal version work for web. So as always, there’s different audiences and markets. For new green field projects, you can bet a lot of people will be interested in this.

      4
  6. 14

    Luigi Maselli

    August 9, 2016 12:58 pm

    Thanks for the article, now it’s even more simple to getting started. The official React tool, create-react-app supports React Native Web https://github.com/facebookincubator/create-react-app/pull/407

    3
  7. 15

    Now that React Native has gone back to the web, the inevitable question becomes:
    When will React Native for Web go Native???

    17
  8. 16

    Dominik Weidenfeld

    August 12, 2016 6:15 am

    I think you’ve made a mistake in the webpack.config.js.


    const webpack = require('webpack');
    ...
    {
    test: /.js?$/,
    exclude: /node_modules/,
    ...

    must be


    const webpack = require('webpack');
    ...
    {
    test: /.jsx?$/,
    exclude: /node_modules/,
    ...

    in order to work for jsx files and js files… otherwise your regex would match .js or .j files ;)

    regards,
    Dominik

    2
  9. 17

    And what about React Native for Server, and we would have one Toll for everything ???

    -1
  10. 18

    checkout https://github.com/ant-design/antd-init/tree/master/boilerplates/MobileDemo

    If we can make components universal, then the app is universal

    1
  11. 19

    I think babel should be a devDependency …

    0
  12. 20

    There are some great developments happening between Vue.js 2.0 and Weex. This new stack is eminent and looks like it will be great for mobile development!

    https://github.com/vuejs/vue/wiki/Vue-2.0-RC-Starter-Resources
    http://alibaba.github.io/weex

    2
  13. 21

    Hi All,
    I wrote an Yeoman Generator to help to create React Native project that includes react-native-web ! you can easily to compile iOS , Android and Web now !

    https://github.com/leeabc/generator-react-native-web

    0
  14. 22

    Rolando Barbella

    August 23, 2016 4:02 pm

    A lot people are already starting to write css in Javascript with react, it is not only react native, some people are still sceptical about this, but it would become more popular really soon

    0
  15. 23

    Have you seen any performance issues when using GPS to enable geolocation features? E.g., I want to be able to show all cafes near me on a map. I’ve been told that react native doesn’t handle this that well…

    0
  16. 24

    I am getting Uncaught TypeError, while running ./node_modules/.bin/webpack-dev-server –inline command. Can you help me resolving this.

    /home/dpc2/TnD/React/RNW/DemoApp/node_modules/webpack/lib/NormalModuleFactory.js:72
    			var elements = request.replace(/^-?!+/, "").replace(/!!+/g, "!").split("!");
    			                      ^
    
    TypeError: Cannot read property 'replace' of undefined
    

    Thanks

    0
  17. 25

    None of this mass mess ecosystem existed when we used rotary phones. People were less stressed and had more free time. They actually talked to one another as opposed to looking down onto their god damn gorilla glass all day. I think I will put RN into the trash and buy me a rotary phone. Good luck to the rest of you.

    0
  18. 26

    Shishir Choudhary

    September 21, 2016 10:13 am

    Looks good to me.

    Look at this as a quick way to get react native apps to run on web. A real problem.

    Question I have is if application is already using redux and react native, would it not be easy to just add web support using say pure react ?

    0
  19. 27

    Or… you could just use LiveCode (Paid or open Source versions) and build for Win, Mac, Linux, Android, IOS and web from one codebase?

    http://livecode.com/

    0
  20. 28

    I tried to make a React Native app I was not able to even setup a “Hello World” application.

    It was actually easier for me to build a completely native app in Java as there are so many more references to working solutions.

    I think I’m definitely over the hybrid app approach. Native just has too many benefits and allows you to actually build with the app in mind instead of questioning if your framework of choice will hold up through milestones A-Z.

    -3

↑ Back to top