This is huge. 87-99% shared code between iOS and Android. Someday companies as big as Instagram won't need to have entire separate product teams for separate platforms.
> React Native allowed product teams to ship features faster to both our iOS and Android apps. The list below shows the percentage of code shared between the apps for some of the products, which could be used as a proxy to measure how we managed to improve developer velocity:
I'm working on a project where we are recreating a native app using React Native. We've found similar results; about 90% of our code is shared between both platforms. We also build both platforms every time, so both apps match really well. I'm not sold on React yet but this is a major plus to the platform.
Yep, I can confirm the same. I've shipped two reasonably complex react native apps, both were about 80-90% shared code.
Areas where we diverged were things like permissions on Android versus iOS, code that has to run in the background while the app is not foregrounded, material design stuff.
To add to the good responses by the others, React Native development, on a good day, feels like the best of web dev and native dev (reload to see the change, `yarn add <package> && react-native link` to add a new NPM package, run the app on devices while debugging with Chrome dev tool). On a bad day, it feels like the ultimate force unification from the worst of both worlds (nothing ever stays stable, ever; were you expecting the app reload to work every time? hah!; running the debugger makes the app crawl, even on recent devices; some packages require you to do lots of stuff for post-install configuration; upgrading RN version will fix some issues but you'll lose half day trying to resolve conflicts between RN and your code and RN and the dependent packages -- then you might get some issues that are unique to the new version of RN; CSS styling -- can cut both ways)
In my particular case, being a solo dev with web background, RN is the only sane option to make an app in Android and iOS in reasonable time.
I'd say it can be a good tech choice, if you plan to focus your work on platforms that React API and ecosystem touch (mobile and web, maybe not desktop).
EDIT: Some grammar cleanup and the bit about styling.
One big negative for me so far is that you can't go the last mile (sometimes even the first) if you don't already know a lot about both iOS and Android development. I've written an app with Cordova and never really touched xcode or did anything specific for each platform.
Also, every library (addon/plugin/whatever) I've tried to use so far has not been even close to up to date with the current version of RN.
Error messages are beyond cryptic.
I'm sticking with it for now, but compared to traditional web dev, it feels like coding in quicksand.
> One big negative for me so far is that you can't go the last mile ... if you don't already know a lot about both iOS and Android development
To me it's actually one of the strongest points of RN. It's not trying to shun away the build/custom native wrapper part in favor of a magical solution; instead, it's giving you full control and full power on how you want things done.
Things like Cordova have been easy and great for simple stuff, but anything that is a little bit different or needs real performance is impossible or extremely problematic to achieve. Not on RN. It can be difficult, as creating a custom native UI requires a lot of knowledge of both native platforms, and a lot of boilerplate. But the end result is superior in every way to what HTML wrappers can do.
Rather than RN being a solution of one-size-fits-all like what some platforms want to be, I look at it from another angle: it still requires native mobile devs with native knowledge, but offloads 90% of the UI/business logic effort to this one universal platform. That's what most no-compromise cross-platform apps need.
I was at the SF React Native developers meet up the other night, the speaker (Devin Abbott) gave several nice pro/con's slide re react native. Here's a picture of the slides:
I don't think Facebook backing Parse is relevant. React Native was designed by Facebook, so I'm assuming they understood the design choices of the mobile ecosystem at the time.
Parse was an acquisition by Facebook that didn't end up working out.
Yeah, it really depends on what your needs are. React Native has a lot of cool features but it also has quite a steep learning curve if you are new to React or new to Native development.
Are you not sold on React, or React Native? If you're talking React for Web, we're in a similar boat, where we want to use React Native for mobile, but for our larger website app, something else....
NativeScript seems very imature for me, especially their promised integration with angular2. Compared to React Native, I really felt that it is not a competitor yet.
This is a bad sign to me, talks about how to optimise start up performance and optimise list views when the processors in our pockets are the fastest they've ever been.
Do we really have to switch to developer centric development where devs have an easier life using JS at the expense of performance?
Think the millions of users would prefer their devices to have better battery life, load faster and have less cruft just to draw a few text boxes of a profile edit screen or a grid of photos (something I would have thought would be effortless to mobile devs in 2017). Rather than the handful of devs having a slightly easier day at the start of the process.
This whole move seems especially strange to me coming from a Facebook company, have we forgotten the move from native > webtech > native already?
I think that is willfully missing the point. Creative work, especially UI-centric product development, requires significant iteration. Layouts change frequently, entire view hierarchies can be re-worked, sizes are tweaked obsessively.
This isn't just about decreasing the burden of engineering (as if Obj-C/Swift/Java/etc. were so hard to master). This is about decreasing the time from concept (e.g. Photoshop mock) to implementation (interactive working app) so that iteration can happen quickly.
As much as I love the performance possible when coding directly against Native APIs, I also have direct experience using web views in native apps. The improvement in the design process around web views is worth investing in getting the performance as close as possible to native. This is multiplied when you consider the cross-platform benefits. However, the performance and UI experience of web views is not good enough.
I can't vouch for React Native giving the iterative benefits of pure web view development nor the performance benefits of pure native development. However, if it does strike a reasonable balance between them I can totally understand why people invest in it.
"React Native uses a JavaScript runtime, but the UI is not HTML and it doesn't use a WebView. You use JSX and React Native specific components to define the UI."
"React builds and maintains an internal representation of the rendered UI. It includes the React elements you return from your components. This representation lets React avoid creating DOM nodes and accessing existing ones beyond necessity, as that can be slower than operations on JavaScript objects. Sometimes it is referred to as a "virtual DOM", but it works the same way on React Native."
This is an important point to note as a lot of the problems associated with hybrid apps in the past come down to them being based on WebViews.
The GP implies that the only reason a company would go with React Native is to make life easier for it's dev's at the expense of performance. That's clearly not true and I believe the GP knows it.
If performance was the only thing that mattered to consumers then performance and optimization would be the only thing Instagram's developers would focus on. Facebook is a public company, it publishes Instagram's engagement, growth and advertisement numbers every quarter. Choosing a technology that hurts those numbers would be a poor decision.
Performance doesn't come for free it often comes at the cost of stability and slower time to market. In the case of React Native versus having separate Native teams it also comes at the cost of synchronizing different product teams and dealing with the bugs that come out of that.
To sum up, if React Native was a poor choice it would reflect in the user engagement/growth numbers and wouldn't last long within a metrics driven public company like Facebook.
So you say that React Native is not just to make life easier for developers, but then go on a rant ... that proves how React Native makes life easier for developers? Otherwise, it is a very big compromise, in regards to UX and performance. UX is not native - it reimplements basic concepts from each OS on its own in JS, which is neither good for UX (it doesn't look or feel right), and performance suffers due to bridge shenanigans, JS VM and shadow view hierarchy (aka shadow DOM).
"So you say that React Native is not just to make life easier for developers, but then go on a rant ... that proves how React Native makes life easier for developers?"
I'm very sorry if my comment came across as a rant, that was not my intent. I actually never made the claim that React Native makes developers lives easier in that comment.
My main point was that raw performance is not the only thing that matters to users. App stability and the time that it takes to get new features to market are also things that users care about, sometimes at the expense of performance.
Facebook/Instagram make product and technology decisions based on metrics. Making life easier for their developers is a secondary concern. If a feature is not moving the engagement numbers in the right direction, it gets cut.
The proof of this is Paper, a beautiful fast native app that was originally meant to the replacement for the main Facebook app. It's numbers sucked, so Facebook cut it.
Paper was never designed to be a Facebook replacement, but a PoC in engagement through UI using Facebook. The released a lot their findings and tools to the OS community as well (Tinder took their animation mechanics). Btw 1 billion DAU would have never agreed to that level of rethinking for the app.
So why not have a virtual DOM-based data-driven layout engine that _isn't_ an HTML/JS stack. Something in a language that is more optimisable and works everywhere, like Lua with C extensions, or OCaml, or Java. JavaScript is hard to get predictable performance from and HTML is extremely complex, we can do better if we're writing native apps (hell, we should have had a better online solution years ago too, but we don't have control there).
" Something in a language that is more optimisable and works everywhere, like Lua with C extensions, or OCaml, or Java. JavaScript is hard to get predictable performance from and HTML is extremely complex,"
React Native is not based on WebViews/HTML. It uses a virtual DOM on top of native views:
"React builds and maintains an internal representation of the rendered UI. It includes the React elements you return from your components. This representation lets React avoid creating DOM nodes and accessing existing ones beyond necessity, as that can be slower than operations on JavaScript objects. Sometimes it is referred to as a "virtual DOM", but it works the same way on React Native."
This is quite different from similar Javascript based efforts such as Cordova.
> why not have a virtual DOM-based data-driven layout engine that _isn't_ an HTML/JS stack
I'm not advocating RN, I just understand the motivations behind frameworks like it. I think "to make devs lives easier" is not a fair assessment. Also, to be fair, JS performance is generally adequate. My own experience with performance on mobile devices often fell back to rendering (e.g. managing textures, making animations smooth, infinite tiled scrolling). Very rarely was raw CPU processing a major concern. My experience may not be typical.
As for other cross platform native development libraries/platforms/etc. - I've had some experience with a few of them (e.g. marmalade[0] which was in C++) and generally they do not work for me. I even attempted to write my own and it was its own monster.
In general, I am personally biased towards Native. I would definitely take RN on a test spin if I was in the prototype phase of a new app. I would use that time to determine if I wanted to bring RN into production or re-write as Native.
What is "adequate"? Any long term task still hangs the business logic thread - the only thread - unless you fallback to native. At what point does constant fallback to native for implementing what is not possible in JS a detriment to development? You may say, multithreading is an edge-case, but is it? I have not been involved in a single project where actual multithreading was not needed.
Also, the way RN is implemented internally, such as async bridge and layout (CSSLayout / "yoga"), it is quite impossible to use native optimized views, such UITableView with reusable views, because this API is designed for synchronous API calls.
The only thing I can say for both of you are that you're both right. We need to optimize for the user and optimize for the people getting the improvements to the user as fast as possible. Anything else is just technical debt :)
> Think the millions of users would prefer their devices to have better battery life, load faster
I'd love to see some testing here. Are we talking fractions of a percent or something like 20% more battery drain? If its fractions I am willing to bet most people would pick an easier life (assuming JS is their definition of easier).
> have we forgotten the move from native > webtech > native
I doubt many have, especially Facebook themselves. What a large cost that must have been for them. To have failed that and be willing to risk doing it all over again with native > "webtech2.0" must say something.
OTOH, this kind of tech is a godsend for smaller shops and solo developers, where having two completely separate codbases (or three if you also do a web version) can be impossible.
Or smaller startups who need to support both platforms at launch. We're going through that right now and we definitely can't afford to pay for a java dev and a swift dev and a js engineer (me). We also can't afford the Dev Shop costs of both iOS and Android. and our customer base is split 65-35. React-Native is literally a gift sent from God to save us
I think almost always, if there was a choice between making thing easier for the developer and squeezing more performance with more difficult practices, majority chose better developer experience.
Especially as chips get faster, teams can afford opting towards a better developer experience to move faster and retain happier engineers. It isn't only developer experience, also developer velocity. That was the whole motivation behind React Native in the first place.
From my experience, any native developers that work with React Native have a mental toll from having to adapt to what seems like unnatural technologies from the native side. Add on top of that the terrible web ecosystem, terrible JS base library (and, perhaps, the language itself), the lack of IDE (not code editors), the debugging experience, the packager performance, and it's just not a good experience for people who have worked in better developer environments, such as Android Studio, Visual Studio and Xcode. The only people really happy, from my experience, are web developers who are already familiar with this technology and ecosystem.
I think the goal here is to target both iOS and Android with just one codebase.
But I also happen to hate this trend, and I see it on Windows too. It seems like companies stopped creating native, good-looking and performant GUI applications built on .NET (or on Win32 which I still would find acceptable), and instead opted for uglier and less performant applications running on some javascript or node.js framework, because those will also run elsewhere.
Could you give an example or two of a beautiful 3rd part .NET or Win32 app on windows? In my mind many of the standard win-forms-esque looking apps are really ugly or have issues scaling on hi-dpi screens.
Unless you are making a video game, or doing high throughput data processing, the JavaScript language is probably not your performance bottleneck.
For the most part performance problems in consumer apps are things like pagination, poor re-use of data structures, over pre-caching, etc.
Instagram never has more than what... 10, 20 elements on the screen? And it's all pretty much text or at most a 10 second video clip. There's no reason even a crappy mobile processor can't handle those elements. It's all a matter of being intelligent about what you put on the screen and when.
There's no need for high performance rich data structures. There's no big data.
I didn't know what single/multi-dex means so i looked it up.
Android application (APK) files contain executable bytecode files in the form of Dalvik Executable (DEX) files, which contain the compiled code used to run your app. The Dalvik Executable specification limits the total number of methods that can be referenced within a single DEX file to 65,536, including Android framework methods, library methods, and methods in your own code. Getting past this limit requires that you configure your app build process to generate more than one DEX file, known as a multidex configuration.
Do Android apps regularly encompass over 65.3k methods? I assume a majority of these would be framework type functionality, but it really seems that a multi-dex product would be near impossible to maintain.
This is one of those Android design decisions that Google probably wishes they could get to do over again. The DEX header file format allocates only 2 bytes to hold the number of methods the app can reference. This was a very short sighted decision that has come back to bite them repeatedly. It would be interesting to know why they only allocated 2 bytes instead of 4 which would have given them the ability to reference over 4 billion methods. If their reasoning was for cost saving measures than it was a pretty silly decision. There has been some talk about revising the DEX header file format to correct some of the early design mistakes, but I'm not sure when they'll get around to it.
> This is one of those Android design decisions that Google probably wishes they could get to do over again.
Doubtful. This decision is what allowed Android to perform reasonably even in the early days circa 2008. Without such a restriction, it's possible that Android couldn't have competed with iOS on performance and die as a consequence.
It's easy to make fun of technical decisions made ten years ago, try to put things in perspective.
Besides, even today, this 65k limit is barely a minor annoyance that only a very tiny percentage of Android apps ever hit (and there are easy workarounds).
> this 65k limit is barely a minor annoyance that only a very tiny percentage of Android apps ever hit
This is not true, you can easily hit this limit because of a dependency that you _need_ that pulls e.g. Gauva, of when you use 2 or 3 libraries from Play Services, which are huge
> (and there are easy workarounds)
Easy maybe, but the issue is still more than _a minor annoyance_ imo
I've hit the limit when pulling in all Play services. The key is to only pull in what you will be using. Many tutorials(including one from a third party analytics API) are a bit lazy and just have you import Play in its entirety.
>Tor: So [regarding] the infamous 64k method [issue].. I understand that it is a dex file format limitation.. which is a short integer. Do you have plans to address this somehow, by either change the dex format or some other way?
>Anwar: So we've talked about revving DEX, so that limitation doesn't exist anymore. And there's a couple of reasons we haven't done that: one, there're other things we would like to do better as well, including supporting new language features. The other reason is - it doesn't help us with devices still in the field. It's hard to go and say "by the way, we're going to upgrade your runtime.."
So what do we do in order to address that? We will do the DEX byte code [change], but I think there's sort of building block that we needed first - what we're calling multi-DEX. And the idea is.. here's something people were doing - they were breaking up their files into multiple DEX files (each of which exceeds the 64k limit), the main classes in DEX file could see the classes and use them in sort of references rather than loading those classes and having limitations in how you can use them. They will go and use reflection to find the boot class path and modify it to include their secondary DEX files. So this is kind of hack, but a necessary one for them.
>What we're doing in L is in runtime we will have a native support for multi-DEX. All your DEX files that you have in your app will get dexopt-ed or compiled by us and collapsed into a single .oat file which is a binary file we generate.. ..And we have a support library on top of that.. ..if you have multi-DEX it will work on older releases of Android back to Ice Cream Sandwich.. will work on Gingerbread too, but we're only validating back to ICS. So once you have that, than that free's you in the future to do the DEX byte code change, and then something that partitions it and runs on the existing [devices]..
One interesting note is that he mentions that they'll hopefully have the DEX revision by M. Well, we're on N so it looks like they missed that target date. Perhaps O will finally get the long awaited DEX file format revision.
Yeah, why they don't enforce this is baffling. I can give them a break for letting their OEM's take their time with OS updates, but not requiring their OEM's to issue security patches is negligent.
Yeah, it's not like Samsung can go make iOS phones. And I highly doubt any of these hardware OEMs could possibly pull off a software project that doesn't suck, let alone a whole OS and dev ecosystem.
Samsung already releases phones running Tizen to have a side bet against Android. The quality of software is not very important when your only competitor builds phones that are significantly more expensive.
So why can't Google create a new version of the dex format, update Android Studio to generate it, and update the store to accept and distribute it to new devices? Seems easy enough for Google to be able to do.
You make it sound like it is as simple as that, only a method table instead of a header field :)
That said, you mention using a varint or uint32 which "use more CPU or memory" -- 16 bits vs 32 bits in applications that use megabytes seems trivial. Can you explain why that's a concern?
It's not a concern anymore, but when Android was created, the average application was less than 20kiB. Back then, resource restrictions were a lot more problematic.
Usually most of the methods are from dependencies. Interestingly enough, some of Google's own libraries like Guava and Google Play Services are commonly what pushes apps over the limit.
True, but Google Play Services can now be cherry picked so you can depend only on what you want to use rather than a blanket dependency. See table one here: https://developers.google.com/android/guides/setup
Iirc, the reason you end up hitting the limit for 65k methods is that each library tends to keep independent copies of its dependencies. This simplifies dependency control, but ends up mushrooming quickly.
That is actually not true. Afaik multiversioning of dependencies is not actually supported by build systems without manual effort (not counting major versions in non-conflicting namespaces).
Problem is really more in fat libraries and "unnecessary" (getters, setters) and synthetic (e.g. access to private methods from inner classes) methods that are usually not optimized away, especially in debug builds.
I've definitely included a library and then seen (otherlibrary).(library you included) as an option in autocomplete, fairly often. Happens a lot with utility-level things like okhttp.
I can't find the okhttp case you reference, but retrofit has a bunch of extra adapter artifacts that add an external library as a transient dependency to your project.
The code for the binding classes lives in retrofit.adapter.{guava|rxjava|…} [0] but the respective library still lives in its usual package. [1]
If that weren't the case you could A) not manually provide a minor version via your dependencies block in your build script and B) would have interop problems between libraries and between a library and your code as the same interface copied to a different packages is not the same interface for Java.
> Do Android apps regularly encompass over 65.3k methods?
No. I've built huge applications that didn't come nowhere near that. I don't dispute some apps might run into that, but it's not a regular occurrence at all.
The real problem here is that it depends on what kind of libraries you're using. If you're liberal with adding a lot of all-purpose libraries when you only need a feature or two, you can run into that limit fast.
For example, look at the comparison table ("Replacing existing libraries") here:
It depends, Picasso is smallest but doesn't support GIFs. Glid is larger and does support GIFs. Fresco is larger again but has more advanced memory management and better transition handling.
There is no practical difference between single and multidex. Recent versions of Android are even better at creating these dex files effectively so users won't even notice the difference.
Most of these methods are typically contributed by dependencies, not by the app itself.
As an iOS developer, I had to decide between investing more time in Swift or React-Native. I chose React-Native simply because I thought it will allow me to broaden my mobile development experience and maybe one day stretch to even the Android platform. Furthermore, it improved my javascript skills in general and allowed me to create React web apps as well. I think it is the right choice thus far. Anyone else have similar experiences?
As someone who was in your shoes last year as I made a job transition into a lead developer role at a new company. I picked React Native for a small project over Swift: https://studio.carnegiemuseums.org/out-loud-cdc979453ef0#.rh.... It was worth it. Not only because immutable render functions make view code extremely pleasurable to write, but also because it's mostly JS and JSX it allowed me to quickly spin up a web developer to work on this project with me. (About 2-3 weeks.)
Now React Native is not without it's downsides though. You pretty much have to know the platform underneath if you want to do anything past API calls and rendering to a list view. (And even that list view does not support the heavy recycling that iOS manages for you.) For the above project I had to write our own Bluetooth, Audio and Accessibility Native Modules.
But the speed at which we were able to develop over a native solution was worth it alone. I highly suggest looking into React Native if your next project is simple enough.
Looking at https://github.com/CMP-Studio/TheWarholOutLoud, I see that you only support iOS. Any particular reason for that? Seeing as you have chosen React Native, why have you not used the number one feature, which is cross-platform development?
Often I see people touting "cross-platform development", but then, in practice, one platform always gets priority, and when it comes to support the other, a lot of the view code has to be rewritten. How much of an effort do you reckon would be required for this app to support Android?
If only iOS was the only target, why did you go through the RN hoop, when Swift would be much more natural?
Sure. The project only had to support iOS, our research shows that about 70% of this museum's goers use iOS devices. So MVP; iOS first.
I wouldn't list "cross-platform development" development as the most important feature to me. If that is the case then I would just as easily used Ionic or Cordova which are far more stable then React Native currently is. Rather it was a combination of things that got me to use React Native for a project:
1. Redux - Single direction data flow
2. React - Pure render functions
3. Ease - Both easier to learn/use and faster iteration times vs. Native.
This project was honestly a testing ground for React Native for my team and it was a small project that if we decided to we could switch to natively without too much of a time hit. We fell in love with pure render functions and single directional data flow and it would be hard to go back to MVC-like architectures. (Yes their are libraries for that for Native platforms but not with the same ecosystem and community behind them as React Native has.)
As for how hard would be to port over? I'd say we would could keep all the logic and would have to redo 40 - 50% of the UI for Android. Which is higher then it would be now because when we started navigation in React Native was the wild west so we dropped into a Native solution.
Our next project however is a cross platform React Native app, which we hope to release by the end of this month. This app shares about 80% - 85% of the code between platforms. We also believe as a team to making apps feel native to their platform so Tab Bars on iOS and hamburger menus on Android, which is why our numbers are lower then other apps that use their own branded UI vs. platform UI.
FYI Tab Bars are now recommended by Google for Android as well http://www.androidauthority.com/bottom-navigation-material-d... There is a lot of data that shows hamburger menus create big discoverability issues and Google highly discourages uses them now.
So if anything the general layout of an iOS app would meet the latest Android Design Guidelines quite well. There may be certain "iOSy" things left like very blurry backgrounds but overall there's little reason to have a different UI layout across platforms at this point.
I think the main issue is that since the Android guidelines have changed so many times in a short period of time, it makes it very confusing to follow the latest ones. Add on top of that even Google's own apps fail at following some of the most established Material Design guidelines, it is very difficult to have proper examples to look at when trying to design an Android app.
That's very true Google has never been as disciplined when it comes to design guidelines. But aside from purity to specific guidelines there is a lot of data that show hamburger menus are death for discoverability of whatever is tucked away in them. Google has been slowly moving away from that direction for years first with the removal of the hardware menu button. As far as tabs go, having tabs, and on the bottom, is tremendously helpful especially on larger screen devices. All things Apple has likely known all along and hence their original design guidelines that Google seems to be adopting more and more of over time.
React Native is so much nicer for building and iterating on layouts and styles it's almost worth considering the switch for that alone. Hopefully Apple is watching and will steal some of the best workflow benefits for some future version of Interface Builder.
> I had to write our own Bluetooth, Audio and Accessibility Native Modules
I hope you open sourced these :)
I was looking at React Native the other day and the impression I got was that almost every piece that does more than display data from the web needed extra modules and far from all of them were written already.
This is true. Some great ones exist (like https://github.com/airbnb/react-native-maps and https://github.com/wix/react-native-navigation), but those are few and far between. Most are very simplistic and only solve very narrow cases. So you end up having to do a lot of the work yourself, for both platforms. And that is a big chore, as there is a lot of boilerplate to integrate native components with RN.
Disclaimer: react-native-navigation is developed by Wix, my employer, but I have not worked on that one.
Sure did: https://github.com/CMP-Studio/TheWarholOutLoud/blob/master/i.... See also CMSAccessibilityManager and CMSBeaconManager. They are not listed as packages on npm though because by the time we shipped the way to construct Native Modules had changed in the latest React Native. :/
Sure. This particular project was 2 engineers working about 4 months from concept to shipping. One engineer had done iOS development since iOS 5 and was familiar with Swift and Obj-C and only vaguely familiar with JS, React and Redux. The other engineer came from a web background using mostly Angular 1.x and jQuery with no native mobile development experience.
Edit: 4 months because many novel solutions needed to be developed. Particularly a coarse indoor location that uses iBeacons and works without internet access and a statistics based learning audio player that alters content order based on what you have previously listened to.
Yep. This describes me. I'm an iOS developer who has been contracting for the last 6 months doing nothing but React Native.
I do hope to return to Swift once the language stabilizes a bit more. It was annoying not being able to easily use any third party swift libraries when Xcode 8/iOS 10 came out (Apple made some Swift language changes and all third party libraries had to update).
All that being said, I'm pretty happy with React Native, its waaay better than any other cross platform solutions I have tried.
It was interesting going to the React Native developer meet up in SF. Very few native developers were present, pretty much everyone in attendance was a web dev.
I think being a native developer who is good at react native gives you a competitive advantage.
Not surprised at the ratio. Wix, Web.Com and other "we'll build you a website for free" sites combined with offshore web devs have commoditized (in management's heads) a lot of web dev work, and they're looking to get in on mobile dev since it hasn't been commoditized yet.
I've had a similar experience. I have had to spend time learning both, I think I am just paranoid about job security! Moving from Objective-C to Swift felt a lot more natural than moving to React Native, getting used to Javascript and the web development environment in general is quite daunting. What were your deciding factors when making your decision?
I think job security was one of my decisions too. Another important decision was the fact that I wanted to be able to use React for both web and mobile apps. Mastering JS was a big bonus.
That being said, it's definitely a smart move to invest time in swift (I did play around with some swift libraries), as it does seem the industry "might" move towards some kind of hybrid obj-c and/or swift + React-native app. I've personally decided to invest more time in JS than Swift.
Yes, the React syntax and JS in general also wasn't as easy for me to catch on vs. obj-c (I wrote a lot of C in my previous job). As you write more, you'll get use to it.
They probably traded a really nice iOS codebase that had been maintained and improved upon for something that is going to end up with tons of special cases for when the UI is running on iOS/Android etc and make it incredibly difficult to test, reason about.
Instead of improving the code on each respective platform, you end up with an inbred red-headed step child that shares the limitations and thorns of each, all smushed together.
Now, making a change that once was once limited in scope to a single UI on Android now has the potential to affect both apps in new and exciting (read: unpredictable) ways.
I've been down this path before. There's something incredibly satisfying about reusing code, but there's such a thing as too much of a good thing.
I'd like to see a case study done in a few years once the whiskers have had some time to accumulate on this codebase.
Steve Jobs knew about the perils of this development methodology which is why he specifically put his foot down on technologies like Flash -- which (let's admit it, folks), React Native really has more in common than we'd like to admit.
I have, and most of what is written there I find correct. Wouldn't go as far as the Flash stuff. Mostly, it's down to the terrible web ecosystem and JS. Feds love it, but they don't know better. Native developers do, and most of the ones I've worked with have suffered a mental toll on having to work with RN. Now, is it an understandable from a management standpoint? Sure, especially at a company like Facebook, where there is a lot of fed experience. Does that make it a good technology? Not at all. It's a terrible compromise that has only one purpose - allow feds to develop on mobile. If only cross-platform mobile development was a concern, something like Xamarin is a lot more technologically sound, but still a big compromise.
Dude, I've been developing on the iOS platform since 2011 and Android not much later than that. I've developed in Xamarin, and RN has a MUCH better development toolchain and dev experience.
I really don't understand the JS hate. I'm using typescript for RN development and I have had 0 problems so far. JS/TS dev velocity is just so much better than ObjC/Java. Swift is a huge step in the right direction.
Not sure how you developed with Xamarin, or how long ago, but it most definitely does not have worse toolchain development. Starting with a proper IDE, to compilation, to native-interop, to performance, to actual base library that exists.
Thanks for pointing that out, forgot my old site was still in the profile.
What do you mean by feds? That's still a very confusing statement. Switched off of Xamarin about 8 months ago and haven't looked back. My organization had a ton of problems with Xamarin, without honestly that much gain at all. We still needed specific devs for Android and iOS. Sharing component and state code has been an absolute boon in productivity and speed in getting a world class suite of apps out. That plus a React stack for Web means I can help out on Web with no ramp up, and vice versa.
We are using Xamarin for our mobile apps and around 90% of .NET code is shared between both platforms. The platform specific code is basically just UI related, which makes sense given the different approaches to some UI mechanics in iOS vs Android. Also leveraging the huge .NET Ecosystem which in general has quite high quality and superb tools for development and debugging is a big plus.
We are also starting to use .NET Core for Backend Microservices which would allow more code sharing and Backend devs could in theory chime in on the mobile codebase quite easily.
With all the cross compiling/ web assembly stuff going on it will probably soon be possible to use a .NET lib in JS frontend code as well.
I agree that RN is a good alternative to this if your team is very JS dev heavy and while i did a lot of nodeJS and Angular in my life, i just loathe the JS ecosystem of today.
In our organization, it ended up being UI code that was the 90% number. The actual business logic code wasn't extremely extensive in the same way that we had to know Android and iOS, and then basically transpile mentally what we know into C#. Though almost all of the core SDK methods are named the same, so it wasn't too huge of a mental switch.
At this point with react-native, almost everything is shared. UI code, business logic, app state, etc. I think the node ecosystem opens our organization up to a lot more possibilities as well.
I've found that 3rd party react-native libraries are about the same quality as Xamarin Nuget packages. Some are good, most are meh.
Also, I upvoted you. Thanks for sharing your experiences.
Let me explain the "fed" thing. React Native's number one "feature" is that web developers are able to join in development, or even start a "native" app where it would not have been possible before due to no native development teams. In the web dev world, "fed" /front end developer/ is usually the term for the front end web developers - this is what I meant. (While iOS and Android is also front end, it seems "fed" is almost exclusively used for front end web developers.) So, normally, anyone that has extensive (or even some) experience with web development, would already be familiar with the ecosystem and concepts, while for many native developers, there is quite the cultural shock from a bad ecosystem, no base library support, very uncomfortable debug tools and a flamboyant community behavior (many ridiculously terrible click-bait Medium articles a la "why I switched from [X] to [Y] and it is the best thing ever" and "How [Z] changed the way I write code and it will change the way software development is done").
I am not sure why you have had bad experience with Xamarin. To me, using .NET for shared business logic sounds like a real winner, but I will give you the fact that it helps with web dev. However, as a purely technological observation and no interest in management considerations, I can only argue against using RN at this stage.
I think you're conflating a BS web dev culture (which is amplified extensively through the internet and feedback-loopy sites like HN) and actual development technologies.
There's always articles like you're mentioning. I mean, go look at articles when Swift was first announced - or even iOS tutorials and forums ca. 2011.
Sharing business logic is a good thing. But it's hardly the number one feature of react-native. We share almost everything, and have almost no problems doing so. It's been a very good thing for our org, while Xamarin was the opposite.
It's also worth noting that we ramped everyone up from being C# front-end to React/React-Native front-end. So nobody really came in as cutting-edge web dev experts, but our developer velocity now is insane. I think React/RN are good things.
A lot of the views mentioned were specifically poorly-performing web views... now they're well performing React Native views, and apparently sharing more code.
React Native (node-style cjs or es2015 module) based applications don't have to be poorly written, or ill-tested. I think a lot of your bias is unfounded, since Steve Jobs saw only web applications on iOS initially.
I would guess one reason for Instagram to go the RN route is simply easier hiring.
For every really good iOS/Android developer, there are probably 10 really good web developers that easily can pick up RN. As a web developer myself, it's a full time job to keep up with the JS ecosystem alone.
I tried learning ObjC a few years back but gave up because of limited time, weird syntax and very slow feedback loop.
Now I am stoked that I can finally build native apps with the web tech I spent so much time learning, and I don't think I'm alone in that regard.
Instagram is the last group that would have problems hiring iOS and Android developers. I'm almost certain that's not the reason for the switch to React Native.
The main reason to switch is that the user cannot tell the difference for their use case, and they get to iterate faster.
I'm not sure if this is still the case, but I remember hearing a year and a half ago or so that the Instagram team was still pretty small then. FB is pretty lean in terms of number of frontend devs - at that time I remember being told the number was ~250 or so, which has probably grown since then.
The thing is that any good iOS/Android developer will know the platform they are working on while good web developer may have no idea what native SDKs offer and end up reinventing the wheel, badly.
I've never used React Native, but I have done a lot of messing around with Apache Cordova / PhoneGap. From my experience, you're probably better off just developing your apps the "standard way" with Android Studio or xcode. I'm sure React Native doesn't have the exact same problems as PhoneGap, but I bet there are some problems. If there weren't any problems, the iOS and Android codebases would be nearly identical. But that's just my opinion... man.
I worked on a medium sized RN app for both Android and iOS which dealt with the camera, photos and the file system. It was 99.98% the same with only 50 lines of _my_ code difference between then (this obviously excludes framework and library differences).
As a business decision, it's outsourcing expertise of the platforms to Facebook, which has plenty of resourses working on the problem. True it's been the holy grail as long as I've been a web dev, but outside of a bit of platform lock in risk it seems like it's come a long way with relatively simple apps like Instagram. It's trading expense for risk.
Do you really think there's much expense to having two code bases for simple apps (as you said) like Instagram?
If these apps are written properly most (all) of any custom logic is done server side and they are just presentational only.
In addition, a good developer/engineer/team that's properly focused on mobile (the size of the team of Instagram) should have absolutely no problem supporting two native codebases.
Think of it as not 2, but 3 different languages. Say your backend is node - your JavaScript developers can all work across the stack. You can keep code standards more or less the same across the whole company.
I opened Instagram the other day and saw a grey error message show up across the top of the app... it said something about a React error. I didn't get to read it well because it quickly disappeared. I thought I was tripping. Good to know I wasn't.
That is the one thing that is difficult in React Native, getting rid of those debug errors. Sometimes they don't make enough sense to know what they are. But we google are way out of them. Sometimes they're related to a compatibility issues, and communication issues between Objective C and RN.
I would not expect any of these error messages to show up in a production build unless it was misconfigured (which it unfortunately sounds like the Instagram build was based on these reports).
Please speak, if you can, on the mental toll the move to web ecosystem has taken on your native developers that have until now developed on respective native ecosystems. In particularly, I refer to having to work in JS, having to install tens if not hundreds if not thousands npm dependencies in order to do the most routine tasks, having to restart packager and clear cache every few runs, etc.
Packager has gotten pretty stable lately, you shouldn't need to restart it anymore. In regards npm modules, you only need to do so when upgrading dependencies which doesn't happen that often.
Call me old-fashioned, but I thought the Android/iOS code sharing nut was cracked: Business logic in C or C++ and UI in Objective-C (iOS) and Java (Android + NDK). As a bonus, you could bolt a desktop UI on top of the C++ as well.
It's certainly possible, but comes with a large number of its own issues:
- C++ is a way more complicated language with the manual memory management. C is way too low level for things like this.
- Complicated builds if you need to use a bunch of C++ libraries as dependencies.
- Much slower iteration.
- Complicated debugging.
- The need to either write (slow) or generate (constraining) the Java/ObjC bindings.
Then there are things like having to reconcile the lifetime of your C++ objects with the Android Activity/Fragment lifecycles, etc.
If I was faced with the decision of what technology to use for a set of typical mobile apps, I would definitely want to avoid the native C++ path if at all possible.
With modern C++ language features, the "complicated language with the manual memory management" a lot less obvious or necessary. Debugging is only complicated on Android, where NDK is pain in the ass for some reason, even after so many years of Google developing the toolchain.
>With modern C++ language features, the "complicated language with the manual memory management" a lot less obvious or necessary
Not completely though, you still have to think a lot more about ownership and object lifetimes (https://www.youtube.com/watch?v=JfmTagWcqoE), which is a lot better than manual new/delete, but still not as simple as just having a GC.
Plus you have to deal with lifetimes of objects proxied to Java code, where something in the Java code becomes the object's owner. Though you can use a bindings generator like djinni (https://github.com/dropbox/djinni) to handle this for you (with some tradeoffs).
>Debugging is only complicated on Android
It's gotten slightly better recently, but it still sucks.
With Swift it's not trivial either, it's not that easy to set breakpoints into C++ code, stack traces on crashes are often not helpful (so any unhandled C++ exception that you didn't catch and convert into a Swift error is hard to track down, etc.)
Lots of apps (that get made, not that necessarily get used much) are basically CRUD web apps with a smattering of native features being used in a very vanilla way (maybe a little geolocation/gps, maybe you can snap a profile pic with the camera, whatever). Your "shared logic" is HTTP requests, JSON-parsing code, and validating text fields. It would not improve productivity to do that in c/c++ instead of just doing it once each in Swift and Java.
Javascript/RN, yes (at the cost of safety). Plus you can't throw a rock without hitting two JS devs, even in my non-tech-hub city.
Go, as mentioned elsewhere in this thread, would also be appropriate for the task (Google, for the love of god, make it a first class citizen on Android and use that as an excuse to refactor your SDK into something that doesn't seem like it was loosely designed by a committee then handed to the Summer interns to implement with no supervision or clear specs).
Are you talking about type safety? Because you can use TypeScript with React Native too, and it's probably a nicer dev experience than plain JS as well.
Web developers are a dime a dozen - very low barrier to entry, both from learning standpoint, and quality standpoint (sadly). C++ developers - a lot less. C++ developers cost more. Native developers who are also willing to learn C++ are also expensive. My cynical view is that with RN, startups are just able to hire a few web developers instead of having to hire native developers, so it's a lot cheaper.
>Bonus: you can test your business logic without having to run it on a phone.
You can do that with JS (or TypeScript etc.) as well. Even Java (or Kotlin) and Swift, or anything really, if you care enough to separate it from the UI parts.
If you really want code sharing without javascript you might try embedding Lua or Go (Google has a project called go mobile that generates android and iOS frameworks from Go projects).
In addition, if you happen to have a slow connection, all you see is blurred blobs instead of pictures. I never experience that with proper img tags because, you know, most major browsers have been doing progressive loading (which works with basic img tags) since several years ago and it works very well in most cases. I don't see why the guys at Medium felt they needed to reinvent the wheel. I hate Medium's layout and since they allow custom domains it's becoming very hard to avoid Medium links at all.
Checking the source the class is "progressiveMedia js-progressiveMedia graf-image" so in essence they don't use <img> tags for control. They could add in <noscript><img/></noscript> though.
At times I feel filling the building with just a few too many smart people can sometimes cause a regression on experience as things are over engineered and too many people struggle to find smarter solutions to solved problems.
Take Google Maps for example, the old tile based version is blazing fast and uses almost no CPU. "Modern" version of Maps makes my MacBook Pro fans turn on almost straight away, chugs and chokes when dragging and although the zoom motion is clearer the actual data display isn't any better.
Probably OT but a bug that's been driving me crazy for a while now. When I open Instagram it reloads the feed every time as if the app had been purged from memory. This means if I accidentally close the app and reopen it my scroll position is lost and thanks to the sort algorithm the feed order has changed and I can't get back to where I was.
See this every time. Also on iOS if you have the app open, lock the phone, and then unlock you will be at the home screen. Almost as if the app ran out of memory or crashed in the background.
To me it seems like the feed is deterministic, that is, even between refreshes it stays the same, and when there are new posts on the top the old ones are still in the same order.
Not surprised to see no mention of UWP (Windows app dev) but I would figure that Instagram for Windows 10 Mobile would also be similar to the iOS/Android apps because UWP supports React Native?
What would be the biggest hurdling block to rewrite the main feed into React Native? As a follow-up, do you think there's a performant enough ListView implementation in RN to build the feed with?
Thanks, Martin, for appearing here. I've read a few times that apps developed in React Native have an odd look-and-feel, or had noticeable touch latency, or aren't performant enough or native-quality. Every time I tried an app built using a hybrid framework, it felt second-tier.
Has that been your experience? When you moved any UI from UIKit or native Android views to React Native, was it worse in any way? Did it require a lot of work to get back to native-quality UX?
I've only seen such thing on infinite non-optimized listviews on old Android crappy phones, but, new listview infra that solves this is coming up soon :)
No plans for powering camera using React Native for now. We already have great native infra for that and regardless, IMHO RN might not be the best technology to implement those kind of immersive ultra-performant flows.
We see space for React Native to grow inside of Instagram on flows similar to the ones mentioned on the blog post.
Great question. First off, worth mentioning there are many performance metrics you might want to measure. On one hand start up times, but since you specifically mentioned Save, I assume you want to learn more about scroll perf (i.e.: dropped frames, memory usage, time to render next pages, etc).
Awesome, thanks for that link! So far I have been pretty happy with react native. On Android myself and another developer I have been working hit some issues around images on Android.
Part of the issues were our own fault: overlaying a transparent image provided by our designers instead of asking for a non transparent one, not using flags like renderToHardwareTextureAndroid.
Others were due to our use of the navigation library, react-native-router-flux, which on Android is backed by fragments. This caused a bunch of overdraw issues (i.e previously pushed views, which were not visible were being rendered in the background). We are planning on migrating away from this routing library to another one.
I'd love to read more articles about react native and performance based on real world examples at scale so please keep publishing them.
To what extent is React Native performance on iOS limited by the fact that an iOS application using JavaScriptCore outside of a WKWebView can't use the JIT compiler, but only the interpreter?
Thanks for the post, very interesting! The post talks about the percentage of the code shared between iOS and Android. Is there any shared code with the web as well, or is that a completely separate react app?
Has anyone tried using the React Native plugin for Windows [1] in a non-trivial app yet? I'd love to hear what experiences people have had with it, and if there's anything to watch out for coming from the RN Android/iOS camps. Any open source apps that makes use of React Native for Windows that you can point me to would be super helpful as well.
I mean, the Instagram App is also available on Windows, with almost all features as the iOS/Android counterparts. So I'm not sure, maybe they are already using that as well?
Great engineering. Instagram always runs snappy and also with low bandwidth (>1Mbit/s). Meanwhile Snapchat does not even know how to download first clicked story video first.
My project (the weather sensor) is using React Native for the Mobile end. I would still like to work on a professional project to really see how well or bad RN is in an enterprise type project. Having used Titanium Appcelerator on a personal project, I find RN much better than Titanium. I assume it's much better than Xamarin as well.
I think learning RN is a good bet because, it is coming from Facebook. I'm not sure if people remember, but FB on mobile was originally built using Webviews and had notoriously bad reviews because it was slow and laggy. It's because of this lesson that they are in a good position to create a competent platform.
I also think as web developers, we should try to understand more of the tooling/language in one of the mobile platforms of our choice.
Did this change occur recently? I've noticed in the past 3-4 months Instagram has become a lot slower. To be fair, it's started to gain some speed in the past month, but I'd be interested to see how this increase in latency coincided with the migration to React Native.
When teams at Facebook roll out features or rewrites like this, they almost always monitor performance metrics so I'm comfortable claiming that React Native is unlikely to be responsible for slowness you've seen recently.
Great Q. React and React Native use difference "renderers". I believe that with the right pattern to use a different set of low level components you could manage to reuse a big chunk, but this isn't something we have tried so I'm not that sure.
I'm currently leading the (soft) transition of a two-platform, not-so-much-shared-code code base (ObjC, Java, Swift, C++) to React Native.
We hit some snags early on (mostly wrt tooling; also prepare to alter your mind set) but as the article states RN yields an astonishing amount of code reuse between platforms as well as heavily reduced turnaround times.
It’s way too early for conclusions/doing a post mortem for our project at this time.
Nonetheless I’d say we’re able to iterate faster by an order of magnitude and the added value of discussing features and domain logic/behavior for both platforms at the same time while enabling UX/UI to get results/feedback faster is a huge win.
That said, I’m really looking forward to the challenges that lie ahead (i18n, RTL quirks, proper unit/feature/integration testing scenarios, non-trivial native bridging, …)
React and React Native are pretty great pieces of tech, hopefully the ClojureScript story for them continues to improve. When I need to make a mobile app again I can't think of a reason I'd write it in Java/Swift.
The story is already quite good (having shipped a production app myself and maintained it for 6+ months). Checkout re-natal for a good template to start.
A lot of that commenter's points are really diatribes without fully understanding RN, or the 3rd party environment around it.
The absolute biggest con with RN is performance. Redux and aggressive shouldComponentUpdates are your friends here. Airbnb's Lottie library (and FB's keyframes) can help with complex animations and the bad perf associated with those.
The dev tradeoffs are 100% worth it.
The end-product tradeoffs are 95% worth it.
We've had to do some things in-house to circumvent some RN bugs, but that time spent there pales by multiple orders of magnitude in comparison to the time saved by starting a cross-platform app from scratch with RN.
I think you might be confusing Facebook with Google.
Ask any app developer that's used React Native or any web developer that's had to create a native app if it has a reason to exist.
Facebook has hundreds or thousands of React developers that - before React Native - could only develop for web. Now they can move their web developers to their native apps almost seamlessly.
And that's a good thing? I'm being serious here. The web ranks among the crappiest user experience I have with software I use today. And when I speak with colleagues who do the web development at the company I work for they seem far from happy with their development environments and process. It's like the presentation, in which MB of JavaScript are required to render a few paragraphs of text with a side bar or drop-down menu, went to the development environment where thousands of dependencies are required to produce "hello world."
The last thing I want is to see yet more traveling down the path of "web app" style development for my phone's apps.
I love react native but only in combination with clojurescript as javascript replacement.
Speaking of high-performance, is anyone here who has some insights how performance would change when swapping JS with cljs?
Argh, now I see why I can't change anything on the Push Notifications settings page. Nice experiment, Instagram, but could you please fix it and let me disable all notifications within the app, not iphone settings?
The dirty little secret about React is that it tries to 'reinvent' the DOM tree, and Web Components will be out soon making it all obsolete. Why not just move to Web Components NOW, and not have to rewrite your view logic in 3 or 4 years. Polymer wins easily. React got a head start, sure, but the W3C standards and native browser support for WebComponents makes React redundant and unnecessary, in the very near future.
I don't know anything about ReactNative. Nor did I claim I did. I am simply stating that React itself is a dead-end technology. I would think no one would want to use ReactNative unless they buy into the prospect of React itself having a long life ahead. But doesn't. It's a dead end. WebComponents are the future and react will be unnecessary.
I really want to look at React Native, but every time I pull up my Facebook app on my iPhone 6, it can take upwards of 30 seconds before the interface is useable.
That's on a very fast connection.
So to me the FB app is so slow, it makes me hesitant to give React Native much more thought as you'd figure the FB app would be THE showcase app for it.
Someone correct me if I'm wrong but AFAIK the Facebook app isn't really using react native yet, just in very small parts (event dashboard). The rest is still plain old swift and objc.
I wouldn't say you are the only one, but upwards of 30 seconds is very slow - I don't know anyone seeing that kind of performance. Perhaps try reinstalling?
> React Native allowed product teams to ship features faster to both our iOS and Android apps. The list below shows the percentage of code shared between the apps for some of the products, which could be used as a proxy to measure how we managed to improve developer velocity:
Post Promote: 99%
SMS Captcha Checkpoint: 97%
Comment Moderation: 85%
Lead Gen Ads: 87%
Push Notification Settings: 92%