React Native Web React Devs, Why don't you use React Native for Web?

darthknoppix profile image Seth Corker ・1 min read

I use React in my job on a daily basis and that often bleeds into side-projects. I've even dabbled with React Native but I've never considered React Native for Web... until I saw this tweet.

I've been catching up on the React Day Berlin 2019 livestream, and the talk by Evan Bacon was awesome.

Mind blown animated clip

I thought the react-native-web project was an oddity but after the presentation/live demo and looking into it more, React Native is really powerful and the being able to write code which is shareable on native platforms and the web is amazing. I had a preconceived idea of what RN and Expo could do but they are now shattered.

Evan asked the crowd the following question, I want to know your answer:

Are you a React developer and why don't you use React Native for Web?

Posted on by:

darthknoppix profile

Seth Corker


My main focus is JavaScript specialising in frontend UI with React. I like to explore different frameworks and technologies in my spare time. Learning languages (programming and real life) is a blast.


markdown guide

IMO, it's just like any other component system out there. It's really cool that it's basically a 1:1 mapping to the react native components, but in web we have the ability to make much more unique designs and take advantage of the whole HTML, JS, CSS world to create some iconic looking products.

Another weird issue would be having users expect your site to behave like an app on their phones because it looks like one. I could see this leading to frustration for users when the site isn't able to do something that any app is able to do, like have camera access.

Also, as someone who's worked on a couple products with React websites and RN apps, the code share between the two has always been pretty small, and while this project looks like it can help bridge that, I don't think the parts of the code that you'd really want to DRY up would be shared. For that I think graphql is a much better tool, since the retrieval and processing of data is where all the real work is done.

That being said, while I've looked into react-native-web, I've never actually used it. And sorry for being all over the place, those are just my gut reactions


Thanks for you response, those gut reactions are good insight.
I want to see how it works first-hand and I'm going to try and play around with Expo and react-native-web soon.

You make some valid points, in my experience code sharing is very dependent on how much you want to take advantage of on native platforms. The more native it is, the more custom and less code shared.

I think the approach has worked well Twitter but their modern app/web experience is designed to be identical across all platforms - I'm tentatively excited to see for myself.


👋 I'm the developer working on Expo for web. I noticed that you said you haven't actually used React Native for web so hopefully I can help respond to a few of your points.

in web we have the ability to make much more unique designs and take advantage of the whole HTML, JS, CSS world to create some iconic looking products.

Not sure what the argument is here, a react-native-web project has full access to React DOM. React Native for web with Expo also has packages like react-native-gesture-handler which enable easy access to iconic native paradigms which aren't often found in web apps.

the code share between the two has always been pretty small.

IMHO there is a lot more to an app (web or mobile) than the stateless components and data providers. Ideally a universal app would be sharing accessibility, theming, safe-area, media-queries (really anything with a context provider). Deployment related metadata, icons, splash screens, etc... The things one probably shouldn't share would be related to the larger navigation architecture, and platform input states (like hover styles).

For that I think graphql is a much better tool, since the retrieval and processing of data is where all the real work is done.

A very good point! React Native for web and GraphQL aren't mutually exclusive tools, I've noticed that lots of developers tend to use them together.


Hey man, thanks for taking the time to respond!

Let me see if I can clarify what I was saying.

Not sure what the argument is here, a react-native-web project has full
access to React DOM. React Native for web with Expo also has packages like > react-native-gesture-handler which enable easy access to iconic native
paradigms which aren't often found in web apps.


I didn't really like react native. Building my UI entirely with components written by someone else, not easily modified. Having to conform to how the apps get exported, yet still having to manually configure lots of things. When deploying apps there was a bit of an insistence to host your JS bundle on a server instead of distributing it with your app. In the case of expo - Expo wanted to host the JS bundle on their own server. It was strangely strict and and rigid. It was difficult to use native libraries sometimes since they were all community-made.

I ended up using Ionic's Capacitor. I could build a web app, with native libraries and optional UI components, and compile it to all sorts of platforms.


Sorry you've had trouble with React Native in the past. The main benefit to using React Native over Ionic is that there is no Cordova anywhere in your project, everything is native.
Also ICYMI Expo added support for self-hosting your app over a year ago now. There is also a bare-workflow for Expo which enables you to easily add any native code to your app (released ~10 months ago). And as of recently you can add native packages very easily to any React Native project with the auto-linking feature created by Expo. It's a part of the react native community CLI and the Expo CLI so it's very accessible.


That's an interesting angle. There definitely seems to be an ideal path and if you want to venture off that path, it's challenging.

I'm glad you found a solution that worked for you, I've had a brief look at Capacitor.

Did the project you create, use many native APIs - how did you find that integration with the native platform?


I was given the task of deciding how to build nearly identical screens from React web in React Native. One major problem with RNW was that our screens existed in web to begin with and RNW works the other way around.

We seriously considered RNW but I think we made the right decision not using it. It's an amazing accomplishment and runs great apps like MLSoccer but for our app it was a hard ask to lead with mobile. For us, we still have mobile developers and RN is only a fraction of the mobile product. So the 1:1 thing is complicated as I know is the case with many places that use RN.

Instead we built a cross platform shared component library that compiles to 2 npm modules, web and mobile. All our styles are in emotion.js or glamorous-native, imports switch on extensions .native.tsx or .tsx and in the end a lot of components we build end up working in both because all our root components work on both!


Sounds like you came up with a great solution to solve the challenges you were facing. It makes sense that it would have been too much effort to go from web to React Native Web.

Does the component library differ much between the two platforms or are is it designed to look visually identical?


Between web and iOS they are almost visually the same and that was our intent. As for Android, we don't share any components there yet. I would imagine the few differences could be handled easily with RN Platform.

I forgot to mention that a lot of people don't consider how dropdowns as they work in the web don't offer the best mobile experience. Having a shared component library with the option to define different components for web and native that use different UI libraries was invaluable. For example, we really wanted to use react-select for web and built something custom for native using the same props interface.

That’s a great point. Different paradigms exist for different platforms. I think drop downs are a component which can vary a lot depending on platform, mouse or touch, etc.

I think I whenever there is a shared code platform there needs to be a way to target specific platforms or features. iOS, Android and web have very different ideas of what a stop down should look like and how it should behave - to deliver the same experience to every platform could be very out of place.

The ability to target different platforms is a part of Expo for web, (it's added in the expo/webpack-config). You can use a .web.js extension to target web just like .ios, .android, .native target their own respective platforms.


We just shipped a financial/banking App with React Native and previous App was fully native. From our experience React Native is OK for iOS but having all sort of issues with Android. We have a very strong testing mechanism but we find that some odd bugs in production App. It's also something to do with Android as well and not just React Native fault. Also performance degradation was very visible on mid range Android devices


The mobile fin-tech app Brex uses Expo for iOS and Android. With things like the Hermes engine being created for Android, the speed increase makes it far more compelling than it was even a few months ago.


That’s a great point, supporting mid or low end phones with stricter performance budgets sounds challenging. I think the closer to native the better for performance.

I haven’t tried anything complex on Android, thanks for the heads up. I’ll keep that in mind when testing.


Sure. If you are using React Native navigation keep eye on iPad as well since we just discovered that app isn't even starting up for few specific iOS versions. It was something to do with launch screens


I am using Flutter Web I can say with certainty that RN has the same problems - no matter how old is the framework and how big the community. Cross platform may be made the UIs, UX, general flow of the app, but, Whenever you grab something native (plug-in) and you are for bad ass problems. The web is a little bit with more age, there are endless possibilities (combining HTML,js,CSS) than both oses. But, The native OSes offer better performance especially in the non-ui stuff, where cross techs actually bring (plugin) overhead. There is no silver bullet for everything..., Only, in some very distance future, with web assembly... Probably in a galaxy too far away


I think mobile development is a complete spectrum now.
You can spend time and make something fully native or use web technologies and be anywhere in between.

I agree, there is no silver bullet - just the right tool right now.


When Flutter recreates core UI elements like text inputs or scroll views, they assume a lot more issues than React Native.


I personally haven't encountered a lot - One problem that I stepped on is this: github.com/flutter/flutter/issues/...


I think you said it "if you are aiming for identical look and feel" well web user expectations are different than mobile user expectations so it doesn't fly

In the "real world" we don't have endless time to build from raw HTML and CSS so we grab off the shelf components and make due... The complexity comes from when the components don't support everything you need which is irritatingly a lot. Only paid products / near commercial products can get around that problem and they only do it by removing customization from you.

I built a data grid for work there is nothing on the market that comes remotely close to that other than paid commercial products / trialware for their paid grid... There's a reason why when you go to toolkits none of the wiring or hard work is done for you. Because everyone wants to make a big box that sells (or spreads) and nobody wants to solve the tiny little problem that takes weeks or months to finish. Like remembering the checkboxes through pagination in a data grid or select all.

All in all this problem will continue and is why we as developers get paid the big bucks. Maybe someone will magically invent a UI/UX engine that focuses on tracking state for components that doesn't take hundreds or thousands of lines of code to access, who knows. Until they do and until that becomes a success, devs will keep taking weeks or months or years to finish projects. And they won't use RN for web because the state management and business logic is the actual problem not the look of it. The look is important and that's why you have UI and UX designers but that isn't the hard part (it might be the time consuming part to get it pixel perfect but it's not like writing a reducer or writing a resolver)


You have an interesting argument, I think the business logic can be challenging but in my experience UI can be very complex and demanding too.

There are countless times I’ve built components to handle very specific problems the client has wanted to solve and although the logic is relatively simple, I can’t imagine creating a functional UI without a declarative UI library like React.

I’ve also tried native development and found constraints on iOS particularly challenging to get right and very brittle compared with flex layout.

I think the you’re point about user expectations is pertinent, the experience the user expects differs from platform to platform and it could be difficult to abstract the differences away and have completely shared code. I think there can be some middle ground though where commonalities are handled with shared code.

What are the most glaring omissions from components you’d like to see to avoid having to roll your own?


You can do it you just have to know your namespacing incredibly well and all the tricks for it. And buy 3rd party controls : )

You can't avoid having to roll your own because that's the job -- make custom components that work. Even in the most seat warmer type of corporate job you are still "rolling your own" by wiring them together and touching the look if only a tiny bit. It's just that the components seem to be missing that extra 10% or 20% of work that if it were there, would make your life incredibly simple.

In no particular order I find pre-built components miss state management, caching, networking, data massaging in other words all the gnarly parts that developers get paid and paid very well to do. And yes I know that components are not supposed to do that but I don't care if they did, lives would be made easier. They will never have those features, unless it's a paid product (or demo of a paid product) because developing it makes huge assumptions that can't be made if you're making it for others to consume. Blame the disjointed nature of the web. It is okay it keeps us employed but it means we are glorified lego assemblers. That is also not a problem (nothing wrong with lego) but if you spend all your time doing "plumbing" type code you have less time for the reality, which in a browser is CSS (styling) and HTML (structure). Everything else is just some shit, invented in the past ten or fifteen years to make developer's lives "easier" but often makes it much harder or has very little value whatsoever unless your product or development team reaches a certain scale. Oh, and jobs. Can't forget jobs, must resume pad with the latest skills. Honestly makes me sick some days.

I don't think there will ever be sharing in the way you think between mobile and web, unless your UX and UI designers and company accepts the compromise that the web will look like the mobile or the mobile will look like the web which they won't. So technical supremacy? Forget it, nobody will go for it if it compromises even an iota of user experience nevermind deadlines. Besides I am not even convinced it is technically superior. You can't use a hammer when you want a wrench and so on.

I'm holding on but if I get irritated enough in the following years I might go back to school and escape this dirty work. Another option is to make my own "company" or cooperative. If it's made I will let you know and you can join me in the nirvana of shared web and mobile components among other things.


Mobile and web are different platforms and often we want to take advantage of this to offer different user experiences. Reusability is great, but having the ability to separate when needed is better.

NativeScript, for example, takes a different approach to code sharing.

I wrote about code reusability for cross-platform experiences (web, mobile and voice) on this article.


From what I can tell, the approach specified in this article is nearly identical to how React Native (for web) shares code.


Good article and good points. The ability to share business logic is paramount and likely prevents the most number of bugs between versions.

I think it’s great to share certain components too but you’re right, there has to be an escape hatch where you can have separate experiences for a platform. There is no one size fits all and a platform should allow for this.


Flutter is here. Flutter is the future. It really is a revolutionary technology


Flutter has memory leaks and a small community. I'll wait a few years first.


The community seems to be growing very fast (the benefit of having Google behind it), have you used it much?

Where are memory leaks likely to occur?


It's gotten a lot better, already. The team is growing and for iOS, there's a metal renderer on the horizon which should reduce memory usage by a lot.


I’ve used flutter a bit, I made a prototype and it was really intuitive. I got a bit stuck with state management though, it seemed overly complex to get some state shared across the app.

How has your experience been?


I have developed Android apps for more than 3 years with kotlin and java. But honestly flutter development is much more pleasant. Flutter community is really focused to solve the problems that exists in native Android. And to be able to create awesome, performant ui that will look the same across both IOS and Android is a great benefit. It's the only platform that can deliver on the promise of write once, run everywhere

That’s interesting to hear, coming from React I found flutter instantly accessible. I was able to create complex and performant UI with animations really easily. I think I’d have to spend a bit more time learning how to properly manage state though.


I don't know man. I once made a mobile app for a project which has javascript backend and web front end (node & reactjs)

Because I didn't know js, I made it with kotlin.

And then I rewrite the app with React Native because it's nice if the entire system use 1 language.

The app is up and running till now. But I hate the time I spent to code React Native. The debugging experience sucks.

Granted, it was 1 year ago, and RN maybe has been much better. But then, since I knew flutter, never again I want to switch back to RN and risk of having a recurring nightmare.

Trying to rewrite my RN app (yet again) with Flutter soon when I have time.

I love ReactJs fullheartedly though. But React Native? Nah man.

If you can enjoy RN, then it's great. But I can't. 🤣


That’s fair enough. You make some good points. I love React but my experience with React Native is limited to side-projects - same with Flutter.

I’ve had issues debugging in both, I think they could both be much better.

I’m just happy there are so many options to choose from, as a dev you so much choice and if you don’t like RN then you can use Flutter. Don’t like Flutter? Try NativeScript or Ionic.


I am more excited by WebAssembly and what is coming


WebAssembly brings many possibilities on the web. I think it opens up a lot of cool things for gaming and delivering more CPU intensive experiences with better performance.

What specific parts of WebAssembly are you most excited for?


What's the point of using react native on the web since there's already react? That's overkilling react's eco system


I thought it was unnecessary too but after looking into it I think it's really interesting.

It allows you to write UI components in an abstract way so it works on React Native and the web. If you're aiming for an identical look and feel across multiple web and native apps then React Native Web is much easier than recreating components in RN and ReactDOM separately.