Hacker News new | past | comments | ask | show | jobs | submit login
React Native at Airbnb (medium.com/airbnb-engineering)
498 points by msoad on June 19, 2018 | hide | past | favorite | 248 comments



"While debugging, React Native attaches to a Chrome Developer Tools instance. This is great because it is a powerful debugger. However, once the debugger is attached, all JavaScript runs within Chrome’s V8 engine. This is fine 99.9% of the time. However, in one instance, we got bit when toLocaleString worked on iOS and but only worked on Android while debugging. It turns out that the Android JSC doesn’t include it and it was silently failing unless you were debugging in which case it was using V8 which does."

Wow, I can't imagine how frustrating this must have been to debug.


I ran into a fun one like that many years ago in IE. The JavaScript I had written was failing, but when I opened up the devtools to debug it, it worked.

It turned out that in that version of IE, the console object only existed when the devtools were open. So a stray console.log call was causing an exception because console was undefined. But when I opened the devtools to see what was going on, console existed and so everything ran just fine.

I suppose that's the kind of error that only bites you once. When you know about it, you tend to never make that mistake again. But that first time you run into it can cause a painful few hours of head scratching and attempted debugging.

Funnily enough, I ran into a React Native error like the one described in the article, where something worked only while debugging. My previous experience with the heisenbug in IE led me to immediately dig into what was different in RN with the devtools open vs without them. So in a way, those hours I wasted in IE back in 2010 prevented me from potentially wasting hours debugging RN in 2017.


Been there, that same bug. This one bit a lot of people I think!


I had a bug that was even worse, and I never found a workaround for IE11.

In this case I had some kind of progress bar that was updated while a report is being generated. When the report is completely generated, the progress bar is replaced by a button.

Except in IE11. At some point the progress bar stopped updating and it never turned into a button. Until you opened the developer tools and IE11 "flushes" the DOM and paints the new situation. So, never having found the cause, we recommended that (internal) customer to use F12 regularly on that page.


"It turned out that in that version of IE, the console object only existed when the devtools were open. So a stray console.log call was causing an exception because console was undefined. But when I opened the devtools to see what was going on, console existed and so everything ran just fine."

Flashbacks commencing.


I've experienced this console.log bug too


Yeah unless you wrap console log you just do this: window.console && console.log('debug msg');

In older Android versions, warnings in modern versions actually crash React Native apps. Can be very frustrating.


Been bitten by the console bug as well.


Programming doesn't change that much after all.

gRPC is just a modern SOAP. There, I said it.


Modern SOAP doesn't sound too bad to me! But then again, I never found SOAP to be all that bad.

I might have been lucky, though. Every time I had to use SOAP, it was just a matter of auto generating a client interface in whatever language I happened to be working in and then proceeding from there. I suppose not everyone was so fortunate.


I found that autogeneration rarely worked well unless the client and the server were using the same tooling.

The monstrous flexibility of xml and soap meant that in practice every soap server interface I had to consume had some quirk or incompatibility with the client I was trying to use.

The worst offender was security extensions.


I had something like that once in native web dev. It turned out that by default when using the debugging pane the browser would disable cache so the issue (whatever it was) disappeared.

Close debugging? It broke again.

Maddening.


> native web dev

That has to be the strangest combination of terms I've seen this month.


I've seen people refer to bare metal Javascript, which sounds even weirder.


Ever heard of PhoneGap or Electron?


Yes, and neither of them are native, nor are either of them relevant to my comment.

What was your point again?


You can disable cache while dev tools are open in chrome but its not the default.


And, annoyingly, if you check the disable box any time you close the dev tools it resets to unchecked. If you reopen dev tools it still remains unchecked.


What version of Chrome did you experience this in? I've never had to re-check the "disable cache" checkbox, even after restarting chrome from a crash state. I am currently at version 67.0.3396.87


I was dealing with a similar bug yesterday. I was using Python (Pyramid/SQLAlchemy/PostgreSQL) and had an integration test that was failing about 80% of the time, but would never fail when I stepped through the test code.

I ended up pairing with another developer, who rewrote the test from scratch and didn't have the issue. I think I know what the problem was, though - the test code called the route in question on one line, then the next line retrieved an object that was modified during the request. The line after that asserted that an attribute of that object had been changed. Most of the time, it hadn't changed; sometimes it had. To make matters work, any time the file was modified it seemed to work once or twice then begin failing again.

I'm 99% sure what was happening is that by the time the object retrieval happened in the test code, PostgreSQL hadn't fully committed the changes to the DB that were made during the request and the object returned was unmodified. Why was that happening? No idea. I suspect it was something to do with connection pooling or the way we were using gevent monkeypatching elsewhere, even though the tests themselves weren't using gevent.

Things like this are both the most frustrating and most fulfilling part of development :)


Thanks for pointing this out. This part was my experience and as you said, it was quite frustrating. Overall the RN experience made me more skeptical about thing I usually take for granted.

It really shows how hard it is for RN to work cross platform. Each abstraction layer can bring in some new problems.


You were the one who had to find this bug? That's pretty neat!

How long did it take for the Aha! moment?


IIRC the whole debugging took half a day. There wasn't exactly an Aha moment either. Enough trying different accounts/platforms/devices/environments made me realize that debugger might have changed the result. Once it was confirmed I actually felt defeated. Hard to feel good when you are hit by observer effect and at the same time realize that the a native JS API could be problematic.


It's really fascinating to read about these in hindsight. But yeah, it must have been a nightmare for them.


fun one was when sort was stable with debugging turned on but not without :P

(or vice versa? i forget)


Yet another company discovers what many of us did ages ago with multi-platform frameworks.

Additional layers not supported by platform owners, mean extra debugging efforts tracking down which layer is responsible, catching up with native SDK features, need to be an expert at both layers, lack of integration with native debugging tools...

But business always wants the Ferrari solution at the cost of a Fiat panda.


I'm not an expert in iOS or Android, but I shipped few React Native apps. Most of my debugging efforts were in webapp. In fact I don't even remember anything about debugging native layer. And I actually built few native components including integration with compass and yandex maps. Sure, it's not Ferrari, nobody outside of US has money for that kind of apps, it was just few hundred bucks for few weeks of my time, but app works on both platforms and customer was satisfied. I think that React Native is great for many apps. If you're world-level corporation with dozens of developers and want absolutely best experience, go native, I guess, you don't really care about few million bucks thrown here and there.

Also don't underestimate a possibility to update app without those pesky moderators. It's awesome, push button and all users are updated.


C++ for business logic, with native views for the UI.

Works across both platforms, does not require additional SDKs and has all the debugging tools and API available without any additional FFI work.


Perhaps Swift is a better to use as a cross-platform LLVM compiled language, as it is very close to Kotlin in terms of syntax and patterns. C++ is a huge language and has a ton of gotchas.


I'm getting a pretty good React Native app working without understanding any Objective C or Swift underlying stuff. Sometimes you just want a Honda.


The real fun starts when you need to do advanced debugging, the toolkit doesn't cover your use case properly or you hit performance problems you can't solve in the non-native language :)


I'm not sure why it would, I'm not doing anything outside of UI logic and interfacing with web services, so it's almost like all other React.js web development for me. Perhaps that's the sweet spot.


Whoa! Whoa! Are you suggesting that the end experience with a programming framework might depend on the details of your specific project and should not be inferred from general blog posts? That's insane! /s


You are getting your users a pretty bad experience because you are lazy and only think about yourself. Users want Porsches, and they deserve them.


Users may want Porsches, but only a few are actually ready to pay for them.


Just like many devs for their tools it seems.


That's just false in most cases. A react native app even halfway well designed is indistinguishable from native.


That's pure nonsense. I have not seen one RN app that looks anything like native, including our own.


Why would it be nonsense, when it outputs native elements, what could give it away?


Because that's incorrect. Yes, it outputs `UIView` objects. But that's far from being native. Just a few examples: a button/"touchable opacity" is not a `UIButton`, it's a custom view where RN fakes the touch animation in JavaScript(!). Gesture recognizers are faked in JavaScript. Animation doesn't use Core Animation but fakes it either in JavaScript or in custom C++ implementation in the Animated module. It's one big lie to call React Native "Native".


Ok, thanks for a more informative reply, I didn't know about how some of the interop between JavaScript and native broke the native bits. That's good to know. Still though, this is a subset of native functionality. It sounds like there can still be two apps one native one 'react native' that are indistinguishable as long as they use that subset. No?


No. I only gave you small examples. For example, system margins and guides are not taken into account by the RN layout system, causing apps to look non-native. Almost everything is implemented reinvent-the-wheel style in RN, which makes it uncanny valley (and thus, very easy to spot).


First of all, we've had people actually praise the app, second, no one deserves a Porsche. Except Bohr maybe :)


While I don't disagree with your premise, "need to be an expert at both layers" is absolutely still true if you build your app natively for each platform (more so, even). At least with a common platform, if nothing else, you can share quite a bit of code, and that alone might make it worth the extra layers.


And “developing” in RN requires you to be an expert in three fields: iOS, Android and the RN layer, which is often buggy. How is that better?


If you are already using React for the web (which I would believe is the biggest reason to use React Native), then the RN layer is pretty much already taken care of in term of expertise.

For the iOS and Android side, that's a constant between the two possibilities.

It's better because now your iOS and Android experts can concentrate much more on what they do best and your React experts can keep working on your UI like they always did.


React “experts” are not mobile experts, and often lack (and refuse to learn) basic mobile principles such as platform standards and accessibility.


I understood 'both layers' to mean both the abstraction layer, and the underlying layer being abstracted. Actually, you might even understand it as 'all 3 layers' here - iOS, Android, React Native.


But the draw of cross platform is that you don't need to be an expert in them! Or at least, that's the advertised advantage.


For the happy path, you don't. And many apps can stick very comfortably on the happy path. I wrote a controller for a video mixer[0] that ran out-of-the-box on Android and iOS using websockets and everything Just Worked. (I still haven't released the iOS version due to lack of test equipment, but it runs just fine.)

[0] - http://bit.ly/buymyapp


One thing weird for me is I've had issues with Javascript UIs on different platforms but Java backends running on different platforms actually have been pretty consistent. Is there something about javascript or UIs (or both) that make cross platform support difficult?


You have control of your entire backends (usually). With JavaScript and browsers, it's the wild fucking west. Modern browsers are better about sandboxing but if you give 100,000 clients a gun, they will find 100,001 ways to shoot themselves.


“business always wants the Ferrari solution at the cost of a Fiat panda“

Isn’t that the promise of computers and technology? What would you suggest that business want?


> Isn’t that the promise of computers and technology? What would you suggest that business want?

The plot twist with software is that the overall cost (including running costs) of buying the ferarri is often lower than the cost of the Fiat panda.


Great article. I started iOS programming in late 2009 and had solid experience of native mobile programming (iOS/Android) and web frontend/backend (RoR/Node.js/React/Go) before I started to use React Native in late 2016. I totally agree with the auther on what work well and what don't work well about React Native. Sad to see Airbnb sunsetting React Native.

In my opinion, 2 of the reasons Airbnb had more and more issues with React Native are:

1. They don’t adopt type checking for JavaScript.

“We explored adopting flow but cryptic error messages led to a frustrating developer experience. We also explored TypeScript but integrating it into our existing infrastructure such as babel and metro bundler proved to be problematic.”

“A side-effect of JavaScript being untyped is that refactoring was extremely difficult and error-prone.”

This is absolutely not just "a side-effect". In a real project, many developers modify the same code base, and the interfaces (Classes, function paramenters, props, etc) are changed frequently. I think type checking system, e.g. Flow, is a must for writing JavaScript code for either backend or frontend. My team is using Flow, and I ask my team members to adopt type checking as much as possible. When I see something like this funcA(a, b), I always ask the developer to change it to funcA(a: TypeA, b: TypeB): TypeC. It is really very helpful, especailly when we need to change code.

2. They don’t ask engineers to keep most code in JavaScript.

“Often times, it is not clear whether code should be written in native or React Native. Naturally, an engineer will often choose the platform that they are more comfortable which can lead to unideal code.”

All logic and UI should be written in JavaScript. Native code should only be used when we cannot do in JavaScript or the performance is very bad.

When I am using React Native, I do miss the simplicity of writing and debugging native code. But when you need to support both iOS and Android, it's great to just keep one code base in JavaScript. Again, espeically when you need to change the code frequently, you don't need to do the some thing twice. (One for iOS, the other for Android.)


Typo. It should be "you don't need to do the same thing twice"


As a user of AirBnb I would be so happy if they just stopped updating the app. They are making it worse and worse. When I travel and I arrive at an airport, I do not need spiffy animations and "fun things to do" in the city I am in, I need a way to quickly find the address of the place or a way to message the host. Stop with all this experience stuff and give me the facts I need right now


Hey, they hired so many people. You can't let them just sit there doing nothing.


Soon to be released: Airbnb Lite


Yep, and offering local things to do is some of the lowest hanging fruit a project manager can grab on to now a days to CYOA on why he hired so many employees.


I couldn't possibly agree more. The annoying minimalism is killing me.

It took me 5 minutes to find a map view the other day because they've buried it so much and floated their "experiences" stuff up top.


>floated their "experiences" stuff up top

That is no minimalism in my hand book


Couldn't agree more. The app's usefulness is most relevant when messaging host or getting directions. There's so much bloat in front of those main uses.


The experience stuff is fine, but they need to seriously evaluate how changes impact users. When a user is on a trip, getting host and address info should be easy.

When searching for a listing, finding the map should be easy.


I concur, I tried looking for a place in Orlando the other day. Instead, I was shown 40% house/apt listings, 60% tourist/Groupon-esque events.


Tangential to this, he says Airbnb has 100 mobile devs writing about 80k LoC of app code, 40K LoC of infra, and 220 "screens". We've got an app with about the same "dimensions", developed in a similar timeframe, with some very complex financial business logic and 2 developers working on it... what on Earth do their devs spend their time on? Is their engineering organization really _that_ inefficient?


My pet theory is that valuation is in part derived from engineer head count.

Please note that this isn't a "I could build twitter in a weekend, why do they even have so many people" comment. I am not privy to the scope of work inside of AirBnB and can't really comment whether a large amount of inefficiency exists - but if it does, perhaps this is a plausible explanation as to how that can be.

For an earlier stage company some mental gymnastics can justify the statement that in the event the startup doesn't become a unicorn 100 engineers are still "worth $100m" to big corporate buyers as a sort of big acquihire. This provides a hedge against failure.

It also provides arguably necessary redundancy during a volatile growth stage. A higher bus factor if you will. https://en.wikipedia.org/wiki/Bus_factor

And so a slightly inflated head count early on based on the above principals ensures that bureaucracy, having reached critical mass, keeps on expanding.

At the present point, there's no plausible scenario for 100 to be reduced to 25 when the company is growing and doing well.

If AirBnB suffers a calamity and its network effects somehow start disintegrating, holding on to these people could ultimately increase the sale price - the brand would have suffered, the apartment inventory is reduced, but you're still left with IP and engineers to hawk.

In the event there are no buyers you could significantly stretch out the runway by multiple rounds of layoffs from this group, claim a successful turn around with the fat trimmed, and raise a new round of financing.


"For reference, we have about 10x the amount of code and 4x the number of screens on each native platform". So the amount of code and the complexity is substantially more difficult than you describe. You probably also don't have as rigorous AB testing, logging, internationalization, contributions to open source, etc.


I used to be a CKEditor core dev. The codebase was 150k LOC of (mighty complex at times)JS and there were four of us working on the LTS(4.x) - we were somewhat understaffed, but not "we need a hundred devs for this" understaffed.

On the other hand last year I spent two weeks working on a project for which I was borrowed from another one - they had a total of 120k LOC(Java, TypeScript), twenty people and at least the front-end was a dumpster fire.

I guess people don't scale well.


I guess quality is a factor, because CKEditor 4.X might have a lot of lines but it is one of the worst library I had the displeasure to use.


I use it extensively in my current project and it is a joy. Different strokes for different folks.


In my experience, in such a large and "app-centric" company the requirements on the app is changing constantly. Just having a specification that you implement is a hundred times easier than building a constantly evolving target.


Also, once you have a lot of developers, the urge to over-engineer grows exponentially


This is often driven by the developers who don't want to appear to be redundant (and who can blame them - everyone wants to hold on to their job!)


Truer words have never been spoken on Hacker News.


So in other words, you think they don't have a spec and they're throwing more bodies at the problem instead of fixing their process? That would be very short-sighted, but it could be possible.


Large consumer apps generally are iterative affairs where the engineers & designers have a big say in the final product. At any given time Airbnb probably has multiple cross functional teams building different features.

These teams are probably constantly testing and iterating the final design based on user research and testing.

At least that was my experience working at Facebook on their iOS app.


You are comparing the wrong numbers. We had 120,000 lines of RN code but RN only accounted for 10-20% of our mobile engineering.


Tbf, there are several very complex host side features and customer support features that are not really readily visible to an Airbnb booker. I was trying to list my space and came across the workflow.


I think this thread gives some good answers to this: https://twitter.com/jandersen/status/1009247005233692672. Basically, problems you get from being at massive scale and supporting a large number of devices.


The numbers are super off yes.

- 1 dev, 9 months project, 16k LoC excluding comments, including UT.

- 16 devs, 2 years project, 200k LoC excluding comments, including UT.


For real... i've had a ~4-5 dev team for the past three years, and our main application code is ~200k lines of java, ~70k lines of stored procedures, and a ton of other ancillary reporting code / etl code which i'm not counting.

I just don't understand where they must be spending their time for an application of that size / complexity.


You are comparing the wrong numbers. We had 120,000 lines of RN code but RN only accounted for 10-20% of our mobile engineering.


That's just the React Native.

It sounds like in total they have nearly 1m lines and 800 "screens". Between 100 devs that sounds about right.

For comparison, Uber have 400 devs working on 3m lines across iOS and Android.


3 million lines of front-end mobile code? That is impressive. How many screens does the Uber app have?


This topic comes up every now and then regarding different start ups. A part of that is required because they're working on some difficult projects, internationalisation is hard, etc, etc.

However, a simple 80kloc system (simple as in no critical safety requirements, very complex algorithms or heavy regulation) is perfectly manageable for a four person team.

A lot of that head count is likely required because they need a large number of employees to attract investment, because scaling start ups are bad at processes (resulting in inefficiencies) and possibly because early employees want to move up the ladder, so they need someone to manage.


That's on average 2 screen per dev.


Others have been coming out and talking about similar experiences with React Native. This thread made the rounds on Twitter and Medium fairly recently:

https://twitter.com/sandofsky/status/1002634185566236679

https://twitter.com/VivekxK/status/1002694526467653632


The common thread I see is that mixing native and react-native is hard. Doing so while working across organizations that may or may not use react-native is doubly so. Sometimes this boils down to the technology, knowledge, and the engineering systems needed to support both but I've also found native developers tend to strongly dislike react-native and lobby against whenever they can.

For me, I'm using it to successfully build mobile apps for a large tech company with very limited mobile developer resources. We've been able to ship Android and iOS apps in a couple months using 100% react-native. I attribute a lot of this to knowing the limitations of the platform and designing a cross-platform experience from the start rather than trying to get the "best of native" out of abstracted JavaScript.

I'll always argue that native is the way to go for the best user experience but react-native is a great tool to have in the mobile space.


>The common thread I see is that mixing native and react-native is hard.

We've experienced some of the difficulties in this area at Facebook as well. If you're curious, making native <-> JS integration more seamless is a big motivation for the ongoing architectural revamp that we've recently posted about: http://facebook.github.io/react-native/blog/2018/06/14/state...

It's a shame we weren't fast enough to help Airbnb in these areas, but the native interop will get better when the revamp is finished.


I did find it ironic while reading it that most of their pain was related to mixing React Native with a large, existing native app, yet that's exactly how you're using it at Facebook. I'm interested to watch how you get on in fixing this.

In my use we've hardly met any of those problems. I work for an agency, and the apps we've used it for are small or medium sized. All are new apps without legacy native components, and none of them mix RN with native outside of plugins. We also use 100% TypeScript now, which fixes a lot of their error-checking issues. Perhaps most importantly, I'm one of the few developers with significant native experience, so we're not encountering the cultural problems that they describe in the posts, of developers resistant to using the tech.


Interested to see what developments occur in this area, it’s a part of React Native I’m very familiar with as the product we are building has a native (C++) audio engine with a React Native GUI. Would be more than happy to discuss what we are doing, our experiences so far, and how we are planning to improve the integration on our end if it might be relevant to what the RN team are looking at.

That said, the experience we’ve had has largely been positive and I don’t think we could have achieved what we have so far given team size and time constraints without React Native. I suspect it gets more painful if you try to combine native and RN GUI elements - our UI is purely RN so there is a fairly clear separation of concerns.


I'm excited about the proposed changes and think they are a step in the right direction, but I also worry that they will add more fuel to the fire that react-native as a platform is a constant moving target.

You obviously have much more insight into what the re-architecture will entail than I do but I've heard a lot of worry around that post with regards to backwards compatibility of third party libraries and in-house native components.


To provide some extra context on this: at FB, we can't ship any RN update (or really, any RN commit) without updating our own apps for it. No product teams at FB are going to agree to rewrite their code just because an infrastructure team came up with a new way to do something.

The reason updates are easier at FB mostly has to do with atomicity of commits. Because FB uses RN from master (and in practice all code lives in the same monorepo), codemods can be applied to products together with the corresponding infrastructure changes. Since the upgrades have a commit granularity instead of the monthly stable releases we cut in open source, there are no big delays between a regression being introduced and fixed for FB products. This discrepancy is unfortunate, but I don’t really see a way around it for an actively developed library--which might be your point.

Undoubtedly RN is in active development, and being a moving target, it's easier for FB teams to “follow” it. Still, large backwards-incompatible changes are just as infeasible for us as for everybody else without either an automated codemod or an opt-in strategy.


I love that development model for internal platforms, but it sounds like you are isolating yourself from the pain points that your customers often face.

My current company casts a weary eye at third party software so the import process is slow and involved. This means we only take major versions, and usually not very quickly. When those versions then introduce regressions in our own products and in dependent libraries it only serves to strengthen the voices calling to ditch the external solution entirely. It'd be a different story if a major version seemed to be of consistent quality to squat on for a while, but each new version brings its own challenges.

To be clear this is all involved in life as a dev in a large software company. For my own personal use I'd rather see RN move as fast as possible. I'm fighting the good fight to keep up (and increase) adoption at work so I just hope that FB and the RN team keeps these things in mind.

Thanks for the additional insight here.


Wow thanks, that explains a lot. So Facebook basically treats RN as an internal library, a single commit can change the framework API and the implementation at the same time so the constant API churn is not a problem.


I'm talking about mostly mechanical changes (think find-and-replace or slightly more involved). Those are easier to do because they can be done on both RN and products at once.

This doesn't work for any larger changes because nobody is able to rewrite a ton of files by hand just to change some API. So this is why we can't make big changes to the API without a gradual adoption strategy, even internally.


That's interesting. Do you think there are situations where it would be beneficial for third parties to use RN from master rather than waiting for releases?


If you have very good integration tests, sure you can try.


Couldn't agree more - AirBnB were already saying upgrading is a pain and this sounds like it'll be substantial.

I hope RN is going to stop relying on beta code for releases too.


Any plans to fix all of the build warnings RN produces for native devs?


I invested a lot into a full React webapp - it would be great to share some of that code with mobile apps. I have an iOS background but was intending to make a RN app so that I could share the bulk of the React webapp code and get Android support as well.

I have separation of container components and presentational SFCs so I’m thinking I could easily re-implement UI layers in RN if I wanted to without sacrificing the shared code. Do you think this is a reasonable approach? Or should I ditch RN completely and build native...?

It would be nice if there was a way I could pull that shared JS logic (which really doesn’t have much dependencies) into mostly-native apps without having to adopt RN... maybe I could just repurpose the JS bridge and be aware of its limitations (a sync/serialized/batched..)


Look into Cordova. It can wrap your static frontend in a multiplatform app that runs inside a chromeless web browser. Super easy to set up and use. Adobe even offers an online build service, PhoneGap Build, which can build Corodva applications for iOS without needing a Mac!

I have successfully used this approach to develop applications for both Android and iOS.


Thanks. I think I might try this out first since there isn't much overhead. What's the performance like for you? Any advice you have on mitigating possible perf issues?


The Cordova browser view is almost as fast as mobile Chrome/Safari. Debugging can be tricky, as in all mobile development, but I was overall satisfied with the available tooling. If your code is performant in the browser it should fare well in Cordova.


I do just that between a web front end I own and a RN app. We write as much pure JS as we can so we can re-use the logic.

For sharing presentation, I'm hopeful for solutions like react-native-web.


Just use RN. It works great for sharing non-UI code.


That was my take away as well, which makes sense. I think trying to seamlessly merge functionality across any two paradigms is going to be tougher than sticking with just one or the other. But for any company with an existing app, mixing in is the most likely first baby step into react native.


It's not just a baby step. For lots of people who are doing more involved work than a thin, straightforward frontend for a server, there are things that are just worse or practically impossible to implement with React Native/JS alone, meaning you'll have to keep falling back on native code. A 100% RN app is simply not feasible for a lot of teams.


Yup it's the classic double layer issue. I think the only way to do it right is to go full 'game engine' style, like flutter or unity. With these you have a very small GL library surface area and one platform stack to actually understand for most of your engineers. Maybe something like WebAssembly will be similar.

You often don't hear about these kinds of issues out of game engine makers. I could be totally wrong although since I haven't worked on games.


Don't forget Udacity removing it from their codebase: https://twitter.com/n8ebel/status/1006244834351312897


Udacity is a bit strange example. This means that they have what? triple size of react native in their main app? That's weird because on android react native blows APK to much larger percentage.


Coursera also removed it completely.


Source?



"Redux is notorious for its boilerplate and has a relatively difficult learning curve. We provided generators for some common templates but it was still one of the most challenging pieces and source of confusion while working with React Native."

Interesting to see even Airbnb struggles with Redux


A big contributor to the difficult learning curve in Redux is the very poor naming of things. It's off the charts unintuitive, especially if you're an experienced programmer.

I imagine their thought process went like this:

Types: People like strongly typed languages, maybe if we call our events "types", they will like Redux more?

Reducers: Switch statements are so boring and uncool. Lets call this "reducer" instead of "events switch statement".

Store: Lets call the state tree "store". The term "State tree" is too explicit and a core principle of Redux is misdirection.

Actions: Mere mortals will associate the term "action" with functions and procedures, but Redux is not for mortals. "Action" will be our term for payload.


Given that Redux is an implementation of the Flux pattern, your grievances may actually be with the naming conventions in Flux itself.

https://facebook.github.io/flux/docs/in-depth-overview.html#...


Your Flux/Redux point is a distinction without a difference. The names are bad, wherever they came from.


This is the thing that everyone seems to have forgotten. Redux didn't invent these terms out of nothing. Redux was specifically written as an implementation of the Flux Architecture, and the terms "store", "action", and "type" came directly from Flux. The term "reducer" had been in use with Clojure already, I think, and is based on the way these functions have the same signature as a callback you pass to `Array.prototype.reduce`. "State" is a generic term meaning "data in your app", and the term "tree" for a hierarchy of objects has been around for ever. (Oh, and you can write your reducer functions with _whatever conditional logic you want_ - switch statements just happen to be an obvious way to handle multiple values for a single field.)

I covered a lot of the history and thought behind Redux's design in my post "The Tao of Redux, Part 1: Implementation and Intent" [0] .

Sure, I'd agree that the terms are a lot to take in for a new learner, but claiming these were chosen or made up to make things more confusing is ridiculous. There was a lot of debate over exactly what terms to use during the development process [1] [2] [3], and it was ultimately decided that keeping the Flux-based terminology made the most sense at the time, because most people coming to Redux were familiar with Flux already. Obviously the dev landscape has changed since then, since nobody seems to remember that the original Flux concept existed, but the terms are now set in stone because we've been using them since the beginning.

[0] https://blog.isquaredsoftware.com/2017/05/idiomatic-redux-ta...

[1] "reducers": https://github.com/reduxjs/redux/issues/137

[2] "state", "store", "dispatch" : https://github.com/reduxjs/redux/issues/113 , https://github.com/reduxjs/redux/issues/137

[3] "actions" vs "events": https://github.com/reduxjs/redux/issues/384 , https://github.com/reduxjs/redux/issues/377 , https://github.com/reduxjs/redux/issues/891


One other addendum:

The "store" is the object returned from `createStore()`, which has the `dispatch`, `getState`, and `subscribe` methods.

The store object contains your "state" value, which could be a simple number by itself, an array, an object, or whatever else you return.

Typically that top level value _is_ an object with other values nested inside of it, and _that_ is your "state tree". So, the "store" contains the "state tree", and they are not the same thing.


The cognitive overhead of redux ends up being pretty high due to the boilerplate in my opinion. It feels like complexity increases very linearly as project size goes. I've found that MobX translates to a much simpler mental model, though it does have a variety of quirks to deal with that Redux doesn't face (like converting objects to non-observable for test case assertions)


Yeah, MobX is significantly easier to reason about, even if it may have a few idiosyncrasies that make debugging more challenging. Also, performance optimization of React components is a cinch with MobX and a nightmare with Redux.


Can you explain what you mean by "perf optimization is a nightmare with Redux" ? Generally, Redux helps improve performance in a React app, especially as you connect more components.


Let's say you have a component deep in the hierarchy that needs to update based on a small but frequent change in a large object (thousands of keys). With Redux, you have to figure out how to diff the old and new copies of that object to figure out what changed. With MobX, you just observe the value of the exact key you're interested in.

That's just one example, but I generally spent a ton of time writing complex shouldComponentUpdate functions and therefore making lots of mistakes with Redux. I've found MobX much more suited to building complex UIs with deep hierarchies and tens to hundreds of total elements on the screen at once, where updating only exactly when necessary is critical.

I use MobX for my game Falcross, which I wrote about in the State of React Native 2018 thread from a few days ago: https://news.ycombinator.com/item?id=17316877

I initially used Redux, and I found it actually technically impossible to get the game to perform well using Redux. I tried everything.


I'd agree that MobX generally gives you good performance out of the box, but I'd definitely disagree that Redux's performance situation is a "nightmare".

One of the keys to good Redux performance is to connect more components, and have each component only extract a small piece of the state [0]. Using memoized selector functions also helps in most situations [1].

FWIW, there was a really good discussion on the relative strengths and weaknesses of Redux and MobX in regards to performance a while back [2].

[0] https://blog.isquaredsoftware.com/2017/01/practical-redux-pa...

[1] https://blog.isquaredsoftware.com/2017/12/idiomatic-redux-us...

[2] https://www.reddit.com/r/reactjs/comments/5hf4d4/an_artifici... (see the linked article, the Reddit comments, and the links in the comments).


I really like that mobx + vuex have their version of "memoized selectors" (computed getters) straight out of the box, fully integrated. They're so insanely useful.


I strongly agree with the 'cognitive overhead' comment.

I think, a number of challenges that Redux and MobX are intended to address, can potentially be resolved in more elegant and easy manner with the new (16.3.1 and above) Context APIs. ReactNative 55.+ works with 16.3.x and 16.4.0 so these APIs are available to your react native apps now.

For example making available global stores to all the components that need them, being able to invoke 'render' on the interested components, when a particular store is being updated -- all of that is being supported. All that without passing the store as property through the hierarchy depth.

for the cases where your component relation is 'horizontal', rather than hierarchical. I recommend simply to use pubsub.js. It is a library that has 0 dependencies (rarity in JavaScript ecosystem :-) ). and has both Sync and Async publishing via channels. So that you can pause your publishing to the horizontally-connected components, if you need to, and then resume -- when the publishing is done.


As a Redux maintainer, I'd be really interested to know what approaches they used, and what sorts of difficulties they had.

(I'll throw out my obligatory comment that you are always welcome to use as much or as little abstraction as you want on top of Redux, and there's plenty of options available to trim down "boilerplate" depending on your situation.)


"Requires boilerplate" will forever be a criticism of Redux unless redux itself takes the (radical) decision to get rid of the boilerplate.

Just saying "well you don't need to use it" means that Redux maintains all that crust and cruft of boilerplate which remains a huge cognitive impact not only on beginners but also possibly experienced Redux users.

Redux is magnificent, but it should take a lesson from create-react-app which did the job of getting rid of all the crap that webpack and babel disastrously imposed on all JavaScript developers with their "maximum config" approach as opposed to zero config.

The message to JavaScript library and tools developers is "get rid of your config or some other tool will come along and do it for you". Redux's boilerplate is just config. If you apply every brain cell you have to the task of getting rid of boilerplate, what would Redux be left with? That's what it should be.

I think the success of VueJS can be laid squarely at the feet of the complexity of the ReactJS ecosystem - not even necessarily React itself. Every part of the larger React ecosystem needs to reduce the cognitive load it imposes and the primary task there is getting rid of configuration/boilerplate.

My theory is that "all software that CAN BE more simple is replaced by some other good enough solution that IS more simple". Thus VueJS, which whilst I wouldn't use it, is certainly simpler for beginners to grasp.


Part of the issue is that _everyone_ has a different definition of what "boilerplate" means.

So, legit question: what do _you_ mean by that term? Use of actions? Action creators? `connect()`? Immutable update logic in a reducer? Store setup?

I honestly get frustrated that people keep throwing around that term, but few people seem to point to a specific _thing_ that can be improved. (People also don't seem to understand the context that Redux came from and the intent behind its original design, something that I tried to capture in an extended blog post a while back [0]).

Early last year, I filed an issue asking for discussion of ways we can improve the learning / getting started experience, and resolve some of these "boilerplate" complaints [1]. There were a bunch of comments and some decent ideas, but I already have a lot on my plate, and no one from the community really stepped up to help push any of the ideas forward.

I do have a small "redux-starter-kit" lib [2] prototype that I've put together as a tool that can help simplify the store setup process and reducer logic. Again, though, I haven't had time to do much more with it myself since I first threw it together.

I am _always_ open to legit suggestions on ways we can improve the docs or find ways to make using Redux easier. Unfortunately, it seems like very few people are interested in actually getting in touch with us and offering assistance in doing so.

[0] https://blog.isquaredsoftware.com/2017/05/idiomatic-redux-ta...

[1] https://github.com/reactjs/redux/issues/2295

[2] https://github.com/markerikson/redux-starter-kit


For me it is specifically this.

Here is a class:

  import React from 'react'
  
  export default class class ChooseFontLevel1 extends React.Component {
  
    constructor(props) {
      super(props)
    }
  
    render = () => <span>foo</span>
  }
And here is the (almost) same class, with the boilerplate required to use Redux:

  import React from 'react'
  import {connect} from 'react-redux'
  
  class ChooseFontLevel1 extends React.Component {
  
    constructor(props) {
      super(props)
    }
  
    render = () => <span>foo</span>
  }
  
  
  function mapStateToProps(store, ownProps) {
  
    return {
      fontPreviewsCache: get(store, `fontPreviewsCache`),
    }
  }
  
  function mapDispatchToProps(dispatch) {
    return {
      onTodoClick: id => {
        dispatch(toggleTodo(id))
      }
    }
  }
  
  export default connect(mapStateToProps, mapDispatchToProps)(ChooseFontLevel1)

To use Redux I need to entirely restructure my code.

And if the comment is "You don't need all that stuff", then why is it an option at all?

Also mapStateToProps is poorly named and confusing because it isn't talking about anything to do with ReactJS component state, although it's a reasonable assumption, it's talking about the Redux state... there's a bag of confusion for you and enough to make a beginners head spin because their head was already spinning about what ReactJS state is.

I'd also suggest that Redux has made a rod for its own back by calling "the thing that gets data out" as "reducers", instead of something like "getters". "Reducers".... argh we're now in computer science land and not the land of the practical programmer. A reducer, what is that? Beginners certainly don't know and you have to learn and become experienced with Redux to come to understand that in fact a Reducer is

Equally, cognitive load would have been reduced if actions were named "setters" or something familiar and similar to the actual functionality.

Redux itself isn't that hard once you understand it, but it's put up big cognitive barriers around itself so that you need to be an expert to eventually discover that you don;t need to be an expert.


Well, the `mapDispatch` example can certainly be simplified. `connect` supports an "object shorthand" - just pass an object full of action creators as the second argument, and they'll all be bound up and passed in as props. So, your `mapDispatch` example can just be:

    const actions = {onTodoClick : toggleTodo};

    export default connect(mapState, actions)(ChooseFontLevel1);

Other than that... there's 1 import line for `connect`, 1 function call to `connect`, and the `mapState` function.

Is that truly too much to write? Also, how does that qualify as "entirely restructuring your code"? Your component is still the same - it's getting data as props. It's just now getting them from a component that was generated by `connect`.

The alternative is to write the store subscription code yourself, by hand, in every component that needs to access the store. I've got some slides at https://blog.isquaredsoftware.com/presentations/workshops/re... that show what that would look like, and THAT would truly become tedious and painful.

The point of `connect` is to abstract out the process of subscribing to the store, extracting the data your component needs, and only re-rendering your real component when that data changes.

As for the naming of `mapState`: the word "state", in general, means "data that represents what's going on in my application". So, there's the generic aspect of "state", there's "state that is being stored in my React component", and there's "state that is being kept inside my Redux store". Those are all valid uses of the word "state" (and especially given that the Redux core is entirely independent of React).

The term "action" comes from its original design as an implementation of the Flux architecture (which is part of my point of people not being familiar with where it came from). "Reducers" comes from the `someArray.reduce()` method.

(Also, note that in both of your examples, the constructor isn't actually needed because you're not doing anything meaningful in there, and your `mapState` example isn't making use of the `ownProps` argument and therefore shouldn't declare it for performance reasons.)


Easy for you (and me to some extent) to read what you say and see hey yes it could be more simple....

What is simple for any Redux-experienced person is a gigantic cognitive cliff for people who are not experts. I can still remember trying to learn ReactJS and Redux and bailing out on Redux while I tried to make sense of mapping dispatch to props. Redux should not be losing users at that point.

Your earlier post expressed frustration at not being able to get people to be specific about what boilerplate is.... well this is it (or my definition anyway).

IMO, ideally Redux would be nothing more than an object that I instantiate and then call methods and properties on - including defining my reducers and actions. A single object for Redux leaves the question of how to ensure that changes to the Redux store result in a props refresh being pushed down through the component hierarchy, but surely the big brains on the ReactJS project can come up with some other way to handle that behind the scenes rather than me needing to change my code structure.

And may I say I love your work and I'm a big fan of Redux!

Although if I found something that operated like I say - a single object to be instantiated and driven via methods and properties with total immutability, with changes resulting in a props refresh on update, then I'd switch.


Unfortunately, the library you describe wouldn't be Redux at all. Part of the core point of Redux is to separate out the act of describing some event or update that needs to occur, from the process of applying that update. That's what makes time-travel debugging possible, and it allows middleware to modify the actions that are passing through the store. In all honesty, if you want objects with methods, MobX is what you're looking for.

Not quite sure what that "single object" sentence is trying to say, but that also sorta sounds like MobX's wrapping up of components with `observe()` (which ultimately does the same kind of thing `connect` is doing, just in a rather different way).

(Also, fwiw, Redux is completely separate from the React team. Dan Abramov and Andrew Clark, the creators of Redux, _do_ work on React at Facebook now, but Redux is not a Facebook project, and Dan and Andrew are no longer active maintainers. We talk with them a lot, and they obviously have a vested interest in Redux, but it's separate.)

And thanks, appreciate the compliment.


> Redux is magnificent, but it should take a lesson from create-react-app

...which is ironic, considering the fact that Dan Abramov (co-)created them both.


Those libs add some "magic" which is going against the point of Redux (knowing exactly what's going on). Instead of those abstraction libs I like to use the observable pattern with Rx or MobX


Depends on what your definition of "magic" is.

For example, we specifically have a "Reducing Boilerplate" docs page [0] that talks about writing reusable logic for reducers and action creators, like "higher order reducers" or a `createReducer()` util that accepts a lookup table of action types to handler functions. There's many existing libs that implement this kind of pattern [1].

Beyond that, there's other libraries that provide a higher level of abstraction, like automatically generating logic to handle common use cases (normalizing data, updating certain fields, etc) [2].

Updating data immutably can become complex [3], so there's a lot of immutable update utility libraries out there [4]. I recommend Immer [5], which lets you write normal mutative code but then applies the updates immutably.

Finally, there's frameworks built on top of Redux, like Kea and Rematch [6].

So, plenty of options available, depending on what you're comfortable with.

[0] https://redux.js.org/recipes/reducing-boilerplate

[1] https://github.com/markerikson/redux-ecosystem-links/blob/ma...

[2] https://github.com/TheComfyChair/redux-scc , https://github.com/Bloomca/redux-tiles

[3] https://redux.js.org/recipes/structuring-reducers/immutable-...

[4] https://github.com/markerikson/redux-ecosystem-links/blob/ma...

[5] https://github.com/mweststrate/immer

[6] https://github.com/keajs/kea , https://github.com/rematch/rematch


It's really amazing to see Redux, and then go and use the Elm architecture.

The Elm architecture is so simple you could write the API on a business card, and it fundamentally does the same thing, and solves the same problem. There's almost no accidental complexity, only essential complexity.

Redux on the other hand feels like there's so much accidental complexity, but it's not even obvious, it's masquerading as essential complexity.


It feels like an emperor with no clothes situation. Redux is obviously terrible but the community has adopted it none the less.


> Interesting to see even Airbnb struggles with Redux

I mean even the creator of Redux says you probably don't need to use it or if you do not all of it. It's overly complex for what it is meant to do, IMO. I had issues figuring it out initially and now if I don't touch it for a few months I feel like I have to re-learn how parts of it work because I forget and it doesn't feel intuitive to me.


Having never worked with Redux, what is its point? Is it really so hard to stick app state in a JS object and databind off that?


Yes and no.

The main point of Redux is to make your state updates predictable and traceable throughout the codebase.

Sure, you can create a global object and stuff your data in there. But, if any random part of the app is allowed to modify that object at any time, then it's a lot harder to understand how your app got into a particular end situation.

Redux is based on the "Flux Architecture" concept, and asks you to follow restrictions on how you structure your logic. Only certain functions are allowed to update the state, and in order to run that logic, you create plain JS objects called "actions" that describe some event or update that needs to occur, and ask the update logic to determine the new state values in response.

This adds a level of indirection to your code, but it provides a way to log and trace when, where, why, and how a given piece of state got updated.

If you've got about 45 minutes, I did a "Redux Fundamentals" presentation at Reactathon a few months ago that walks through the basic principles of Redux. Here's a link to the video and the slides:

https://blog.isquaredsoftware.com/2018/03/presentation-react...


In a simple app, no. In a really big app with tons of interdependent, asynchronously loaded state? Have fun.

Redux definitely has too much boilerplate, but it does an excellent job of keeping functionality decoupled, and on a big project this ends up being way more important. When you do it right, you rarely introduce regressions when working on new features, because almost everything you do is additive: you're adding new state, new actions, new selectors, new sagas, etc., without touching any pre-existing functionality or anything that pre-existing functionality depends on.

The alternative is playing an endless game of whack-a-mole as an app gets too large for anyone to keep track of what depends on what.


> The alternative is playing an endless game of whack-a-mole as an app gets too large

An alternative is another state management library.


Yeah sorry, I didn't mean to imply that redux is the only option. I meant that whack-a-mole is the alternative to using some sort of robust state management approach.


>Due to a variety of technical and organizational issues, we will be sunsetting React Native and putting all of our efforts into making native amazing.

Buried lede. Why not just say it outright?


Airbnb has managed to over-engineer a Medium blog post.


It's Airbnb!


Very good write-up, thanks for posting.

Some of the frustrations definitely hit home. I think for small teams and indies React Native is an awesome piece of technology that can enable them to target both platforms where it would be nearly impossible otherwise. I can understand how orchestrating the work of a huge team could introduce new issues though.

It would be interesting to know why some of the infra layers that the article mentions (i18n, networking) were behind bridge when they seem like prime candidates for js implementation.

What I'd really like to know though is how other teams are managing the design pipeline (getting from psd/sketchapp to code without hand coding flexbox styles). We've looked at some tools like supernova.studio and BuilderX, and while showing promise these seem like they have a long road ahead.


we have a new tool that we're trying internally to design cross-platform components - https://github.com/airbnb/Lona

pretty early still, but the idea is that short-term it generates assets that fit into our existing Figma / Sketch product design workflows for consumption. having a cross-platform source of truth for _components_ is higher impact than outputting their _consumption_. this was mostly the reason we first did the things we wrote about here - they laid the groundwork for Lona and a more component-centric design process. https://airbnb.design/painting-with-code/ https://airbnb.design/sketching-interfaces/ https://airbnb.design/the-evolution-of-tools/


Thanks very much. I'll take a look at Lona.

A couple of days after I posted that I started thinking about whether it would be possible to develop a sketch plugin to render react components onto artboards, then I googled my way into your react-sketchapp and a talk you delivered at ZEIT. You guys are doing some really cool and useful work. Thanks!


We wanted to leverage our existing infra to have a consistent experience between native and RN screens. For example, you want to have the same network cache.


Re: your last sentence, Pagedraw (YC W18) is a good choice for going from design to UI components and features great Sketch and Figma integration.


Thanks for the pointer. That does look interesting. RN not yet GA though?

I also noticed Framer announced an upcoming tool 'Framer X' with React support -- not sure if that includes RN either.


What's wrong with hand coding flexbox styles?


If we can help designers realize their designs in software without requiring an engineer, that would be a great thing.


I’ve never seen anyone do a battery impact analysis of React Native. I wonder why?

Person sally, I don’t want to use products where the developer prioritizes their problems over my experiencs but YMMV. Some will argue that an Electron dumpster fire is superior to nothing. I consider that debatable.


RN is nothing like an Electron app though. Rendering is fully native, no browser engine involved. It does add not-insignificant overhead due to JSC, Yoga and native bridge, but it will depend a lot on the nature of the app.


Eh, I can almost guarantee it has almost no battery impact. JavaScriptCore is fairly fast, business logic doesn't take that long to run (100ms vs 200ms, whatever.), and it all pales in comparison to running GPS or the display for a few seconds. Unless you're playing a game or running some complex algorithm, most of your phone's battery goes to the wifi / cell radio and the display.


I agree with you, that for the same 'business logic', having it JavaScript vs native, unless you do lots of sorting/copying of data -- will not have battery impact difference.

However, React itself (not the javascript engine) brings in additional dimensions, that are somewhat unique to react.

For example, React's (and therefore ReactNative) TextInput control, essentially (in my understanding) encourages you to update a state variable, every single time type a letter into that control

(because the values displayed in the control are coming from the state, so the only way to display the character you typed, is via updating the state).

So that round trip of the character update, to updating the object with state variable, calling .setState, forcing the re-rendering, will consume more battery power. In my view

(I know textinput in particular has the 'uncontrolled model').

My point, that the constant 'create new object', update the state with it, and Re-render -- could be slower (and less battery efficient), than doing may be something similar (or more efficient) in Native Code.


Repeating what someone else has said, React Native is not Electron.


I am still waiting for tide to turn and for times when users mattered to come back. Not sure if it ever will.


I don't buy this sentiment one bit. In my opinion this nostalgia is almost entirely unjustified unless your primary metric of "when users mattered" is "software used less RAM and CPU". Which may not even be factually correct from a percentage of available resources perspective.

Modern day software applications are far more accessible and usable on average than those of the 90s and 00s. And that's the metric that actually matters. More people are able to do more things with software.


What is wrong with TurboLink 5? Not Turbolink 3 or previous version, v5 is very much a total rewrite. Turbolinks 5 allows hybrid Apps that offers most of the benefits without many of the complexity, it is HTML after all.

It seems there are sites that uses Rails, including AirBnB. But I have yet to seen a site that uses Turbolink apart from Bassecamp, even Github uses its own version of pjax rather then Turbolink.


I use the turbolinks libraries for iOS and android and the experience has been great.


I am just wondering if there are any pitfalls. While not many are writing about their technical failure of React Native or whatever tech it is. You will at least know they have changed the stack, or words on the street / twitter they are retrying new things because old things didn't work etc.

But TurboLinks 5? None, not even a mention or beep. As if no one is using it. While we are happily using it someone else may be running into issues we haven't yet doubt with.

It is pretty much like Startup news, I don't want to read about how you succeed this just once. I want to read about your thousands other failure, what works, what not, and what you ( Or I could ) learned from it. By stating your problem, your intended solution, and the results I could make a better informed decision somewhere down the line. And all the time we got on the internet is everyone cheer leading mindlessly.


My guess is that orgs that want a dynamic frontend are choosing SPAs over turbolinks, and orgs that want to serve static pages aren't bothering to put in the nonzero effort to make turbolinks work.


Excuses my ignorance. I don't understand how we could do 99% or even 100% with "pages", but instead we still insist on "apps".


This is a really good write up and I love how they were cautious not to feed the ongoing fanboyism in for and against React Native folks.

Say what you like but this is a very mature move from a young engineering organization.


> Say what you like but this is a very mature move from a young engineering organization.

Airbnb is ten years old at this point, I'm not sure that really counts as young!


I have to agree. It was really interesting that they highlighted that nearly 2/3rds of their engineers would use React Native again. I also assumed that the last part of the blog series was going to be mostly fluff / product announcements, but their efforts in server side rendered native screens and drastic reductions in build time are legitimate takeaways from devs who are used to development cycles at React-Native speeds.


Server side rendered native screens just seem like fancy words for browser to me…

I get that it’ll have native performance and responsiveness, but still maybe just touch up your website and call it a day?


Ah, my mistake, it should say "server-driven," which is more accurate. The view isn't actually rendered on the server, it just seems to be sent over in a declarative format, which the client then renders into a native view.


> sent over in a declarative format

like HTML?

> which the client then renders into a native view.

A WebView?


No


Sorry if the short response seemed rude. No is the answer to both of your questions.

RN isn’t just “HTML in a webview” like PhoneGap or Cordova: elements are actually rendered as native UI components. E.g., a <Text> element becomes a native UILabel on iOS and a TextView on Android.


You have to wonder how many of their 100 engineers are going to dislike having to become iOS/Android devs.


The vast majority of the 100 always have been and are still Android and iOS devs. React Native never made up more than 10-20% of our mobile engineers and many of them came from Android or iOS backgrounds.


How's FB's RN team reacted to Airbnb's decision to move away from RN?


For me, in order of enjoyable front end developer experience it would go iOS > web/js/react > Android.


Really curious as to how Flutter (and Xamarin, NativeScript, Ionic, Vue-based write-once frameworks, etc.) can overcome the difficulties expressed in this piece.


At the risk of being flippant, few companies are building major consumer mobile apps like Airbnb (100 mobile devs is massive compared to the rest of the market), and many are building data-driven business apps. That, or they don’t have the history of native app dev so they don’t have existing native engineers or apps. So while most of the technologies mentioned above wouldn’t work for Airbnb, they work great for a huge chunk of the market. At Ionic we work with teams every day that are meeting their mobile goals with our tech, so we don’t live or die by what works for Airbnb or not.


My guess is that Flutter will conquer the majority of data-driven business apps, since it is the closest multi-platform mobile framework to native code.


Flutter's approach is more like "similar UI and UX in all platforms" so I don't think that you need to write native code that much compared to RN. Also, it uses Dart seems to be a better fit for them compared to JS (static typing, better syntax etc.).


Me too. Last time I played with Ionic it was still mostly wrapped webviews though. And Vue-native is actually the worst. It transpiles Vue code into React Native code that then gets sent across the bridge to native apis.


Sorry, have you got any source for the vue-native part? I haven't heard of that and I'm interested.


Check out the landing page at https://vue-native.io/ at the bottom, "Compiles to React Native". It's important to note that "Vue Native" isn't officially endorsed by Vue.js.


I've tried pretty hard to get into RN with a few hobby projects and I've given up. I'm wondering if PWAs are the way forward for the average data driven mobile app.


I would say they can be, depends on how they evolve.

On Windows they have access to the native APIs if signed and delivered via the store, as Microsoft is building on JavaScript development story they introduced with WinRT.

https://docs.microsoft.com/en-us/microsoft-edge/progressive-...


My money is entirely on PWAs :)


tl;dr:

> Due to a variety of technical and organizational issues, we will be sunsetting React Native and putting all of our efforts into making native amazing.


While i don't have much experience in RN, but have a decade of mobile native development (android + iOS) and two years of React.

The whole 10 years there were people that think that they can just get "web" technology and speedup mobile development.

Almost always this companies had no mobile engineers that know how this stuff works. Developers that know that you just can't listen to scroll and update animations by sending messages to background js thread. This just completely wrong on mobile. Most mobile devs spend months to make it fast and easy to use. There are no way to do this in most cases on RN. AirBNB's app is a perfect example of this. Trying to deliver "better" experience they completely kill scrolling performance. Even top level iPhones feels laggy. But yay! We have animations! AirBNB's app is barely usable on two-year-old androids. This is just simply wrong, this is not how you can achieve good performance and nice animations on such small devices. In most cases this is a kind of art and a lot of testing and tweaking for every device. This can be done by only ONE talented developer per platform per year. Surely AirBNB has resources. Just take specific screen and tweak it to hell. On the other side, react and declarative kind of state is really doesn't work well for non-page oriented apps. Mapping history of navigation via redux store is just an awful and useless idea that helps with nothing. Right now there are still no navigation library.

Every time i tried to start something in React Native i failed since i wasn't able to apply my skills to make it behave fast there are just no easy way to do this.

React Native for sure is a good thing, but it's evolution shaped by web devs that try to reflect their experience from web development, but building a good mobile app is completely different from web one. For example, there are no dom, UI manipulation is not slow, navigation between pages and keeping it's state is not a problem most of the time (there are no real "back" button that you have to handle somehow). UI frameworks are more mature (while have less API than HTML).


> Right now there are still no navigation library.

React Navigation and React Native Navigation are both viable options with their own pros and cons. Been using them successfully in different projects.

https://reactnavigation.org

https://wix.github.io/react-native-navigation


I think what they meant is that there is no built-in production-ready navigation library, which is honestly atrocious.


I never understood the obsession with native navigation libaries.

I built a bunch of apps with JS navs and nobody ever complained...


Did you test your app with VoiceOver, the iOS screen reader for blind people? The difference between non-native and native navigation is particularly noticeable in that case, unless perhaps you fire a UIAccessibilityScreenChangedNotification after navigating to a new screen.

That's just the scenario I'm aware of. I haven't done any real projects with React Native, so there may be other pitfalls.


Of course not. They are a lazy developer that care little about the user experience.


As passionate as I am about accessibility, I try not to use an accusing tone. There's no way we can know the state of mind, priorities, and constraints of the developer in question. Even large companies don't have unlimited resources. So we can't fault developers for looking for ways to do more with less. We just need to do what we can to make sure developers are informed about the pitfalls, and plead with them to consider important user experience factors like accessibility.


"Built-in" and "native" don't mean the same thing last time I checked.


I think you mean 'built-in' into react native? Facebook routinely lets the community settle on the correct api aside from a limited core.

E.g. react router on web has gone through many versions and there are several community libraries for doing web navigation and how you want to track that application state.


And as a result there's a ton of churn, waiting for third parties to update their libraries (sometimes forever) and beginners having to make choices on how to do the most basic things without the experience or knowledge to help them make good decisions.


It's just beyond the needs of fb and what they cared to provide for. No one is paying for the extra dev work, so until some other entity pays or volunteers that will be the situation. Incidentally, Expo did extend RN to cover many of the missing APIs. It's just the reality we live in.


> that they can just get "web" technology and speedup mobile development.

RN isn't really web technology. It is a JS engine along side a cross platform API translates API calls to the appropriate underlying native platform code. UI components rendered by RN do not use web tech at all.

It is no different than Xamarine in that regard, and has many of the same drawbacks.

> AirBNB's app is barely usable on two-year-old androids.

I never had problems with it on my Nexus 5x, and everything was a lag fest on that phone. (Lag in daily use got so bad after moving to Android 8 that I had to get a new phone just for my sanity.)

For a large # of apps, RN works just fine. Its real promise is not "web technology", so far as it is 99% code sharing across platforms.

The other players in this market don't have the same community drive that RN does, so people gravitate towards RN.


I haven't used React Native, but I've ready a few posts from people adopting it. They typically test the waters by writing new app views in React Native instead of rewriting everything. But how much cognitive overhead is there in maintaining multiple toolchains (React Native and native and/or web views) and debugging views in different languages in one app?


I work on an app that is written with a combination of iOS native code, JS, and server side code.

It’s not easy to debug at all. The problem they mentioned where your stack traces just end at layer transitions is a real problem. Even if the server side isn’t involved in the bit you’re working on.


If you can use Expo you're probably good to go without much tooling.


The article doesn't seem to explain specifically why RN didn't work for them but I believe that the real pain for them is to organize 100 engineers to work on the same project.

Often they were confused about native vs RN approach and had to write native libraries and integrated them with RN which requires 3 different teams to write & test and integrate their code. I can see that if one of the teams is either slow or run into strange bugs, they will be the bottleneck and slow down all of them.

From this perspective, similar to why Netflix or other large organization choose micro-services rather than monoliths, it would be better for Airbnb to develop 2 different native apps separately rather than having 3 different teams depending on each other.


I remember mid 2017 react native and the upgrade pain distinctly. It took a full week to set exact versions and run yarn outdated over and over, pull up the release notes one package at a time, try bumping the version, see if it breaks, try the next version, no that’s broken, try bumping react, no that breaks the other one, etc. It was hell.


I have come to same conclusion. Have few production apps and an ongoing one in react native. Dealing with native code has been frustrating, additionally plugins would not be up to date as well. Going native would be a better choice.

I would though love react jsx syntax for building native views in swift/Kotilin.


Kotlin doesn't need JSX, as it already has features for building DSLs for such things[1], allowing you to easily express hierarchical structures as perfectly normal Kotlin code.

[1] http://kotlinlang.org/docs/reference/type-safe-builders.html


None of the recent articles or HN comment threads about React Native spend much time evaluating Haxe. I guess it's not that widely used for CRUD apps and is more popular for games?

Anyway, I'd love to know how it would work for an Airbnb-like org.


As I understand it, Haxe is best suited for writing cross-platform games, not applications that use each platform's native widgets. That would make it a non-starter for me because of accessibility.


It is same with Xamarin. They don't have people that would know these languages, and they would be passionate about them.


Xamarin and co suffer from the same dual layer issues that react native has when I last looked into it.

C# isn't that popular from a silicon valley engineering perspective, since the first class C# implementation wasn't open source until very recently. Yes mono has always be OSS, but it has also been a second class citizen too.


Only Xamarin.Forms introduces another layer for you (it is the same concept as React Native). If you use Xamarin.iOS and Xamarin.Android you call underlying APIs directly. Although there can be issues with bindings, nothing like you will face with React Native.

I am aware of why C# isn't popular among startups. It is sad because C# is a great language that has amazing tooling support. It runs everywhere - Xamarin for apps, ASP.NET for servers, Blazor for browsers, and it is getting only better, and I cannot imagine how awesome it would be if other companies helped Microsoft. But I can only dream.


I think F# and .NET Core may become popular among certain kinds of startups (FinTech, logistics, etc.). It's a good compromise between Java and something like Haskell, in my opinion.


Even with Xamarin.Android/iOS I read about unique bugs that resulted in you needing to be an expert in both layers to understand. And bugs in the wrapper themselves.

It's a problem with the entire design type, which has been shown throughout computing history to not work that well.

And why use C# when the Java ecosystem is pretty much the same tooling wise? C# feels like a 1.2x better Java, which isn't enough.


As someone that works daily with Java and .NET platforms, C# still has a better stories around AOT and value types.

Also Sun really bombed their Java Gaming initiative (who remembers that JavaONE?) with C# becoming the C++'s complement in most studios.


On the web side, yeah, though on the game side C# is very popular (largely thanks to Unity).


On desktop side as well, mainly because most developers never bother to learn what takes to make Java UIs look good like other native UIs do by default.

Even basic stuff like switching to the native L&F theme on startup.


Also on the industrial and automative world. Lots of tools will be written in C# there. Often with WPF visualization.


Well, you can use Haxe with React Native instead of plain Javascript. If you are looking for a way to build mobile apps, you can try HaxeUI v2, based on OpenFL. http://haxeui.org/


I wrote a few weeks ago about how ridiculous it was for AirBnB to spend 18 months testing a new font. A 5 part series on React Native is again next-level indulgent.

Why am I not surprised engineers at Airbnb have so little to do than to write a novel about a framework?


fwiw it wasn't 18 months "testing" a new font - most of that was font development with an external partner, then implementing across many surfaces without creating bugs that affected accessibility, then testing. doing things takes time, huge surprise right?


Yeah nothing weirder than engineers writing about their experiences with different technologies.


A 5 part series. 5!!


I was looking forward to using RN but I guess I fell victim (again!) to whishful thinking and the "No silver bullett" fallacy. Come to think of it, why have we accepted React as the go-to approach to this degree? React doesn't even make an effort to isolate from HTML and DOM at the conceptual level, and I'd wager an opinionated framework about "panels", "fields", "field groups" and events is more representative of what folks typically want to do with React, rather than manipulating pseudo-markup using JSX however elegant and neutral.


I feel like we’re missing a lot of the story. Many of the React Native issues sound painful, but they handwave away a lot of the complexities and drawbacks of their new architecture.

For example their answer to RN’s one second rebuilds is a custom Android build configuration that eliminates most of their 5 minute builds. They are proposing a custom server rendering setup and don’t know how to solve the hardest problems like wiring up events (HTML anyone?).


It looks like if you have small team and you want to develop iOS / Android prototype fast RN is good choice. This case you're looking not for "best user-experience" but "okay user experience fast".

But for big companies java/kotlin or/and Objective-C/swift native apps will be more efficient.


well, its unfortunate that React Native didn't work for them. i think RN is great solution and direction for mobile in general. sure it can be improved but at the moment, it is the best we have for cross-platform mobile development.


Have you tried Flutter? That's looking promising.


Yeah... but... dart.


Is there actually something wrong with the language? If it's a matter of the issue of having to learn a new language, it's not as if there were many Objective-C, Swift, or Kotlin developers before mobile.


Started learning Dart and I like it a lot.

Not sure what the issue is except that it is yet another language to learn.

Google designed it to be easy to learn for other devs. I am mainly only experienced in Java and some Kotlin, and I found Dart easy to pick up.


If you are a small startup using react native makes sense. If you are a billion dollar company why not just have a team for each platform. Or better yet have have 2 teams for each and let them compete for whose product gets shipped.


Resources, even at a semi-large company, are finite. Teams have limited head counts and usually an ever increasing list of asks from Product team. Being efficient is not optional.


Lets do a little math. FB has 25k employees. Lets suppose they pay everyone a million buck. That is 25billion. Their gross profits were 35 billion. They can afford to have two teams or 3 teams or 4 teams working on the app. I don't know what Airbnb's numbers are, but I am sure they can afford to have multiple teams.


I can't tell if you are trolling or not.



Reading a bit between the lines and keeping in mind that rumour that Facebook was removing RN from some of their projects…

Could it be true? Does AirBNB see the writing on the wall somehow?

I know that RN is open source and people will continue to support it and everything will be great, but without Facebook behind it, I wonder how much traction it’ll have.


That rumor was thoroughly debunked (see the discussion in the original HN thread: https://news.ycombinator.com/item?id=17216628).

Please don't repeat and spread false rumors. It cheapens discussion about legitimate technical choices that organizations make.


"keeping in mind that rumour that Facebook was removing RN from some of their projects"

Where are you getting that from? The React Native team at Facebook just put out a roadmap that seemed to indicate they were still very committed to the project and investing in it:

http://facebook.github.io/react-native/blog/2018/06/14/state...

"At Facebook, we're using React Native more than ever and for many important projects. One of our most popular products is Marketplace, one of the top-level tabs in our app which is used by 800 million people each month. Since its creation in 2015, all of Marketplace has been built with React Native, including over a hundred full-screen views throughout different parts of the app."


Isn't React Native end of lifed at Facebook? The effort is taking the best principles of React Native and focusing on Litho https://fblitho.com or ComponentKit - the effort to have a unified framework for both iOS and Android is pretty much abandoned.

I think React Native is in legacy support mode rather than active innovation.


Nope they posted a blog article[0] last week about their plans. Please check your facts first next time because there’s been nothing from Facebook to indicate that.

[0] http://facebook.github.io/react-native/blog/2018/06/14/state...


No, it's still being worked on. To quote their latest blog post:

We're working on a large-scale rearchitecture of React Native to make the framework more flexible and integrate better with native infrastructure in hybrid JavaScript/native apps.

http://facebook.github.io/react-native/blog/2018/06/14/state...


I can't find any reference to that with Google. Mind sharing a link?


This was recently making the rounds, I suspect this is what OP was referring to:

- https://twitter.com/sandofsky/status/1002637340291018754

Responses from someone at FB:

- https://twitter.com/sophiebits/status/1003101478427357184 - https://twitter.com/sandofsky/status/1003104331833532416




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: