[HN Gopher] Five years of React Native at Shopify
___________________________________________________________________
Five years of React Native at Shopify
Author : onnnon
Score : 137 points
Date : 2025-01-13 22:08 UTC (3 days ago)
(HTM) web link (shopify.engineering)
(TXT) w3m dump (shopify.engineering)
| nadis wrote:
| I thought the section on the importance of native devs and how
| they're staffing mobile was really interesting:
|
| "Native devs are crucial
|
| Mobile engineers who specialize in iOS and Android are essential
| to building great mobile apps. There is no replacing experience
| and taste that comes from having built many mobile products and
| deeply understanding conventions and usability. Being able to
| drop down to the platform layer, write bindings, master build &
| release, distribution, etc requires native expertise.
|
| They also play a vital role in optimizing app performance across
| the myriad of device models, ensuring a consistent user
| experience for all users. Additionally, native expertise is
| essential for managing React Native version updates, as well as
| adopting new features, APIs, and tooling changes that accompany
| new iOS and Android releases. You can't build a good product
| without these experts.
|
| We invested in training our native mobile developers in React
| Native through a self-serve course that covered everything they
| needed to know to ship production-ready code. Additionally, we
| set up office hours with developers who were already proficient
| in React Native to provide support through Q&A sessions, pair
| programming, and code reviews.
|
| We also supplemented our mobile teams with some web developers
| for their Javascript, Typescript, and React expertise. This
| ensured we had strong expertise in both native and React Native,
| and over time, it levelled up the entire team.
|
| Having a good mix of native and web developers is the key to
| building great mobile apps using React Native in our experience.
| "
| sdflhasjd wrote:
| Probably the first "we adopted x" blog post that I can find
| relatable and spot-on.
|
| I think it's one of the big misconceptions that React Native is
| _the_ path to get your web devs or even existing code onto
| mobiles. That's how you get the criticism that RN builds bad,
| mouldy apps.
|
| Between our clients that have had this issue with quality and
| shops in the same space as us that haven't (one who boasts a
| review on one of their apps being "an example on how to build a
| proper fully native app"), having a good portion of native devs
| on the team is a big differentiator. Unfortunately this means a
| RN Team isn't as cheap as some hope.
| breckenedge wrote:
| Glad they spent some times discussing the downsides. I'm 4 months
| in to a Hotwire Native replacement for an unmaintained React
| Native app. The differences are stark and I could definitely see
| myself picking up Hotwire again for another project if given the
| same constraints, but I've had good experiences with React Native
| in the past too. Ultimately though I just do not like all the
| work that has to go into maintaining a large scale React
| codebase.
| mattgreenrocks wrote:
| Curious what you meant by the last sentence there. Does React
| uniquely complicate maintenance as a codebase grows?
| breckenedge wrote:
| Theres a constant churn of a bunch of dependencies. Devs add
| minuscule libraries all the time. And I think some of the
| best React libraries have been abandoned, which is kinda sad,
| but nice from a maintenance perspective.
|
| React very much feels like programming using only side-
| effects and that's not really a fun experience IMHO.
| Performance issues are also somewhat difficult to spot in
| review and not very elegant to solve.
|
| It's been a few years since I've used React Native so maybe
| things are better now?
| tensor wrote:
| This is my experience with all javascript stuff these days.
| If you leave the codebase even for a few months now you're
| spending days updating it to all the new breaking library
| changes. Worse, if your tooling is out of date you're
| probably spending a week just fighting to fix/change/update
| the tooling. It's the most brittle tech stack I've ever had
| to work with.
| endlessvoid94 wrote:
| This is the missing criteria in the technical decision
| making, IMO. How reliant is the team on the
| recruiting/retention of the current size and structure of
| the talent, both on the team and in the wider community?
|
| Small teams trying to keep burn ultra low vs. giant
| companies might have similar technical goals but opposite
| staff capabilities. This is a crucial factor.
|
| A second-order effect is how much time/energy/money you
| have to throw at maintenance. Can you afford to spend X%
| of your time on maintenance? Which technologies offer
| comparative advantages on maintenance cost? These are
| surprisingly often easy to answer, and nearly never
| explicitly considered!
| Calamitous wrote:
| > These are surprisingly often easy to answer
|
| I agree that maintenance costs are often
| overlooked/ignored, but I'm curious how you get answers
| on the costs. I've never found it particularly easy to
| get reliable information on maintenance costs.
| nozzlegear wrote:
| > React very much feels like programming using only side-
| effects and that's not really a fun experience IMHO.
|
| This is interesting and I like the way you've phrased it.
| Are you talking about React Native, or React in general?
| And do you use hooks?
|
| I like React on the web, but only when using hooks and only
| because I haven't found anything that I like more than it.
| I still find it tedious and overly hook-y1. It also gives a
| lot of wiggle room for devs to shoot themselves in the foot
| with useEffect, like some of my previous clients have done.
|
| 1 Hold on, I gotta pull in 18 hooks from across my project,
| npm dependencies and react itself before I can write the
| jsx in what would otherwise be a 10-15 line fooButton
| function.
| breckenedge wrote:
| Yea precisely. Hooks themselves are OK, it's just plain
| ole code reuse, necessary the language itself makes that
| somewhat difficult. But then you're not programming JS
| anymore -- you're wed to React and nothing else. I hate
| how it takes over codebases.
| WorldMaker wrote:
| > I like React on the web, but only when using hooks and
| only because I haven't found anything that I like more
| than it.
|
| After being thrown into the Angular woods for a while I
| found that what I really wanted was just a "React with
| RxJS Observables that look like writing Hooks if you
| squint, but don't have some of the complex rules either"
| and then I realized that I was basically trying to
| reinvent some of Knockout, but with TSX templates. I'm
| still amazed by how much I was able to accomplish from
| that idea, including some of the "advanced" features of
| modern React, in a relatively small package (modulo the
| one and only one dependency on RxJS).
|
| I don't know how many other developers want the same
| thing.
|
| (I know some find RxJS overly complex, which is exactly
| why Angular is as awful to work in as it is, both in how
| it badly uses RxJS (and teaches bad habits) and how
| there's generally three ways to do everything, one with
| RxJS and two others avoiding it or misusing it, with now
| a fourth way of Signals which are just RxJS-lite with
| Knockout-style `computed`, proving time is a flat circle
| and Angular remains a design-by-committee mishmash of too
| many things that don't interoperate well. I think
| learning Angular's mishmash is far worse than just
| learning RxJS well, but I also spent a lot of time doing
| Rx in C# and in CycleJS for a while, too.)
| seemack wrote:
| I was glad to see the discussion as well but it feels like the
| downsides were also very understated. Working on an RN app as a
| native dev requires a lot of cross-domain knowledge that isn't
| typical for a native dev.
| Lucasoato wrote:
| Is there any benchmark about Hotwire Native screen response
| time?
| fidotron wrote:
| This strikes me as curiously defensive, in that Canadian way of
| praising things that are obviously problematic to draw attention
| to them.
|
| The wider noise around React Native is seemingly that it works,
| especially while iterating on things, but it makes the final 20%
| of work much harder than it already was. As one person put it to
| me recently "with RN you just have to face the fact you won't be
| winning any design awards".
|
| What really amazes me is how far React Native and web React have
| separated, to the point using the web one is a complete non
| event.
| bloomingkales wrote:
| I just kinda looked around the Shopify app to get a feel for
| it. There are a few frameworks that tap into native view
| switching (transitioning between pages and tabs), which creates
| _most_ of the native feeling (along with native view components
| like lists /menus/switches).
|
| I don't know why the quality of the app feels cheap, but it
| just feels so (the web views load in with zero ease, they just
| jank onto the screen. So while you have native screen
| transitioning, you still have this low quality feeling of a bad
| nypost article shitting out an ad popup on you. Hard to
| explain, but that's my my general feeling).
|
| Regardless, while not impressive, it's in this non-
| impressiveness that informs my unwillingness to invest into
| native or something like Flutter. These apps are too simple to
| go through the hoops.
|
| Shopify RN app is a good example of a mundane non-sexy tech
| decision.
|
| Overall nothing beats CSS and JavaScript for UI, but even in
| 2025 we cannot reliably push 60fps.
| fidotron wrote:
| I disagree with you on a few specifics, but I think the more
| general question does become what should the Shopify app be
| like? Non sexy is, as you say, probably the right call.
|
| For mobile apps generally I cannot recall the last time I was
| actually impressed by one. The reverse is often true, such as
| with Sonos. Individual features (again Sonos, the calibration
| it can do) can be neat but experiences as a whole have gone
| off a cliff, React Native or not.
| mdhb wrote:
| Flutter does 120fps no problems and has for some time now.
| Its also a lot nicer to work with Dart than Typescript.
| treksis wrote:
| Not sure at shopify size, but I highly encourage startups to use
| cross platform for mobile distribution. React native's OTA update
| alone is already worth for fast movers.
| zffr wrote:
| > Our apps are blazing fast (<500ms screen loads)
|
| I'm not sure I would consider 0.5 seconds to be _blazing_ fast.
|
| I wish the article went into detail on what these screens do and
| what a screen load means exactly.
| canucker2016 wrote:
| You'd hope they benchmarked the old native iOS app and the RN
| app.
|
| Since the blog post doesn't mention previous native-only perf,
| I'd assume they didn't compare or the RN version isn't close to
| native-only perf (leaning heavily towards the second reason).
|
| Looking at a previous blog post, the first hunch seems to be
| correct - the second may also be true.
|
| From 2024 March, https://shopify.engineering/improving-shopify-
| app-s-performa... talks about how their RN-ified app was
| loading screens in 1400ms (P75) and the steps they took to
| reduce that to 500ms.
|
| I hope they benchmark their load-screen time with every
| release/CD to stay on top of any regressions, otherwise,
| there'll be more mad scrambles when the perf debt piles up too
| high.
| buzzerbetrayed wrote:
| That was my initial thought as well. Anyone know what native
| screen loads typically are? I'm sure it varies wildly between
| apps, but 500ms seems like it would be on the slower end of a
| "fast" app.
| cellularmitosis wrote:
| For typical apps, the four variables here are backend
| latency, network latency, client-side deserialization, and
| client GUI rendering. (Less commonly, apps which have complex
| client-side state will also spend time reconciling server and
| client state.)
|
| Keeping UI rendering under 16ms is the gold standard for
| native apps. That leaves only deserialization as the other
| target which the mobile developer can optimize. However, the
| typical solution there involves convincing the backend to
| ship a different format (i.e. switching from JSON to binary
| PList or to SQLite DB file).
| zffr wrote:
| It really depends on what a "screen load" means exactly. If
| its just rendering the screen from some client-side data then
| I would expect something <16ms. To support 120fps displays,
| it would need to be <8ms.
|
| If a "screen load" includes making a network request to fetch
| data, then this is a very weird metric to include in a post
| about React Native. Most of that time budget should just be
| waiting for the request to complete. Just as before, it
| should take <16ms to render the screen once the data arrives.
| irskep wrote:
| I agree with most of the other comments here, and it sounds like
| Shopify made sound tradeoffs for their business. I'm sure the
| people who use Shopify's apps are able to accomplish the tasks
| they need to.
|
| But as a user of computers and occasional native mobile app
| developer, hearing "<500ms screen load times" stated as a win is
| very disappointing. Having your app burn battery for _half a
| second_ doing _absolutely nothing_ is bad UX. That kind of
| latency does have a meaningful effect on productivity for a heavy
| user.
|
| Besides that, having done a serious evaluation of whether to
| migrate a pair of native apps supported by multi-person
| engineering teams to RN, I think this is a very level-headed take
| on how to make such a migration work in practice. If you're going
| to take this path, this is the way to do it. I just hope that
| people choose targets closer to 100ms.
| fxtentacle wrote:
| I would read the <500ms screen loads as follows:
|
| When the user clicks a button, we start a server round-trip and
| fetch the data and do client-side parsing, layout, formatting
| and rendering and then less than 500ms later, the user can see
| the result on his/her screen.
|
| With a worst-case ping of 200ms for a round-trip, that leaves
| about 200ms for DB queries and then 100ms for the GUI
| rendering, which is roughly what you'd expect.
| fidotron wrote:
| If you are good those numbers are an order of magnitude off.
| In truth it is probably mostly auth or something. If you
| simply avoid json you can radically attack these things fast.
|
| RTT to nearest major metro DC should be up to 20ms (where I
| am it is less than half that), your DB calls should not be
| anything like 200ms (and in the event they are you need to
| show something else first), and 10-20ms is what you should
| assume for rendering budget of something very big. 60hz means
| 16ms per frame after all.
| x0x0 wrote:
| > RTT to nearest major metro DC should be up to 20ms (where
| I am it is less than half that)
|
| over a mobile network? My best rtt to azure or aws over
| tmobile or verizon is 113ms vs 13ms over my fiber
| conection.
| fidotron wrote:
| With times like that you'd be better off with Starlink!
|
| I'm not joking: https://www.pcmag.com/news/is-starlink-
| good-for-gaming-we-pu...
|
| Are you doing the 113 test from the actual device, or
| something tethered to it? For example, you don't want a
| bluetooth stack in the middle.
| x0x0 wrote:
| straight off my android phone by disabling wifi then
| moving through my 2 sims
| pinoy420 wrote:
| Don't take the bait. It is a typical hn hyperbole comment
| gf000 wrote:
| What percentile? Topics like these don't talk about the 5G
| connected iphone 16 pro max, but have to include low-end
| phones with old OS versions and bad connectivity (e.g. try
| the same network connectivity in the London metro, where
| often there is no receiption whatsoever).
|
| As you reach for higher percentiles, RTT and such start
| growing very fast.
|
| Edit: other commenter mentioned 75% as percentile.
| cellularmitosis wrote:
| 100ms to render an iOS screen means dropping 6 frames. That
| would put an applicant in the "no hire" category.
| joaohaas wrote:
| Since the post is about the benefits of react, I'm sure if
| requests were involved they would mention it.
|
| Also, even if it was involved, 200ms for round-trip and DB
| queries is complete bonkers. Most round-trips don't take more
| than 100ms, and if you're taking 200ms for a DB query on an
| app with millions of users, you're screwed. Most queries
| should take max 20-30ms, with some outliers in places where
| optimization is hard taking up to 80ms.
| bluGill wrote:
| People have gotten used to that, but UI work back to the
| 1960s has done studies and showed clearly that for many of
| these operations you get tens of ms before people notice and
| their attention wanes. The web often doesn't allow for
| response times as fast as the humans need, which is a good
| reason to write real apps not web apps. That is also why I
| use tabs - load a bunch in the background so when I'm ready I
| can just switch tabs and it is there.
| x0x0 wrote:
| > _Having your app burn battery for half a second doing
| absolutely nothing is bad UX._
|
| Why are you assuming the app is either burning much battery or
| even doing more than waiting on current data from the server?
| For an app that I would assume isn't much use without up-to-
| date data from the server?
| freedomben wrote:
| Assuming the 500ms is mostly delay for fetching data over a
| socket, unless the code is really broken that should not really
| be burning battery. <500ms for display of non-trivial network-
| fetched data is great regardless of whether it's rendered by
| react native or is a fully native app. They would both be
| I/O-bound on the network primarily, with a small but
| insignificant compute overhead for RN. If the data needs lots
| of transformation (though not compute-intensive transformation
| like calculating hashes or somethign) upon returning that could
| make a difference, though again I'd be surprised if CPU for RN
| vs native was all that different.
|
| As an Elixir dev who aims for and routinely achieves <10ms
| response times, (and sometimes < 1 ms for frequent endpoints
| that I can hand optimize into a single efficient SQL query,
| which Ecto makes easy I might add!) I find the response time to
| be the more egregious part :-D
| epolanski wrote:
| Make a single example of an app that from when I click to the
| opening takes less than that.
|
| I've just tried whatsapp, notes, gallery, settings and discord
| out of curiosity, none did and I have a very fast phone.
| lelandfe wrote:
| 500ms is the 75th percentile speed, so 75% of users are having
| load times faster than that. For context, Google's synthetic
| p75 loads emulate a crappy old Android phone on a bad network.
|
| A linked post[0] says their p75 was 1400ms before 2023, yowza.
|
| [0] https://shopify.engineering/improving-shopify-app-s-
| performa...
| pinoy420 wrote:
| 2 seconds to wait for a webpage to load isn't even that bad.
| If you take an average user on facebook it is horrendously
| slow - to someone who knows how fast something can be - but
| no typical user cares/notices. They just accept it.
|
| Nike's website is phenomenally quick. But again. Ask anyone
| if that is what they care about. Nope. It's the shoes.
| afavour wrote:
| > Having your app burn battery for half a second doing
| absolutely nothing is bad UX. That kind of latency does have a
| meaningful effect on productivity for a heavy user.
|
| The implication is that React Native is to blame for this and
| I'm not sure that's true. What would the ms delay be with pure
| native? I have plenty of native apps that also have delays from
| time to time.
| tempfile wrote:
| > Our apps are blazing fast (<500ms screen loads)
|
| Hahaha we are absolutely cooked.
| seemack wrote:
| Blazing fast is a bold claim. I use this app nearly every day on
| a brand new Pixel 9 Pro and, while much improved from a few years
| ago, it is far from "blazing fast".
|
| For example, I just recorded myself tapping on a product in the
| Product list screen and the delay between the pressed state
| appearing and the first frame of the screen transition animation
| is more than half a second. The animation itself then takes 300ms
| which is a generally accepted timeframe for screen animations.
| But that half second where I'm waiting for the app to respond
| after I've tapped a given element is painful. UX studies indicate
| 0.1s as a number where an application no longer feels
| instantaneous. (https://www.nngroup.com/articles/response-
| times-3-important-...)
|
| Contrast this against something like the Slack app where the
| screen is navigating even before the pressed animation has
| appeared. Or for an app with probably not as much engineering
| focus, Fastmail, which begins the screen transition within 100ms
| of the pressed animation state appearance.
| no_wizard wrote:
| I wonder a little bit why this is slower on Android than iOS.
| On iOS I've never experienced this, and my phone is a couple
| years old now.
|
| Not saying I have the answer, but it is a curiosity
| seemack wrote:
| It's a good question! I've been hearing the joke for years
| that RN architects don't have any android devices to test on.
| qt31415926 wrote:
| On our apps we consistently see a p50 3-4x speed difference
| between iOS and Android (though there are more lower end
| android devices). Hard to fathom if it's all due to
| variability in android devices vs RN being less performant
| on Android.
| ge96 wrote:
| Developing for Apple can be a PITA with their strict
| background processing rules, apps just terminate/stop working
| unless they fall under a special case. I get it but yeah.
|
| edit: by terminate I don't mean crash, it just stops code
| execution an example is an active socket connection getting
| disconnected unless it's doing something like streaming audio
| humptybumpty wrote:
| The quality standards are so low... half a second to switch
| screens is ok? Jesus!
|
| Apple just keeps making billions and billions by focusing on UX,
| when other "tech" companies are satisfied with this garbage.
| negative10xer wrote:
| I was just showing my team this article. We'd start getting
| warning alerts if our P75 page load times reached 500ms. I
| wonder if we're measuring load times differently.
| gf000 wrote:
| It's also their P75 target load time.
| calvinmorrison wrote:
| Personally I miss the old QT interface with plugins capabilities
| prophesi wrote:
| I'm surprised that there was no mention of Expo. In the past, I
| would say bare-metal is better than Expo-managed React Native
| projects because of the limitations when it came to native
| modules. Fast forward to today, and anything you can do in a bare
| metal RN app can be done with Expo.
|
| The biggest game-changer recently is Expo's Continuous Native
| Generation[0]. You can configure all of your native modules and
| ios/android files with a simple config file (which has its
| limits, whereby you'll need to write an Expo Config Plugin[1]).
| You will no longer commit the ios/android native code to your
| repository, and instead let it be procedurally built.
|
| This resolved a lot of environment issues developers would often
| run into, and greatly simplified onboarding new devs. You can
| build your iOS/Android apps through the CI with ease. And you'll
| no longer be afraid of upgrading React Native, as Expo will
| handle all of the breaking changes in the native code for you.
|
| My guess is that Shopify started with bare metal React Native
| apps (which I would have done the same 5 years ago), and now
| migrating back to Expo-managed projects is nontrivial. At my work
| we only manage one app, and it was well worth migrating back.
|
| [0] https://docs.expo.dev/workflow/continuous-native-generation/
|
| [1] https://docs.expo.dev/config-plugins/introduction/
| methods21 wrote:
| What would be amazing is if Swift and/or Kotlin could just be the
| 'native' language across both platforms and work at native speeds
| on both platforms.
| te_chris wrote:
| https://skip.tools/ Swift can be!
|
| Saw this the other day and looks interesting
| nyantaro1 wrote:
| I have not dived deep into it, but that seems to be the purpose
| of kotlin multiplatform https://www.jetbrains.com/kotlin-
| multiplatform/
| justinko wrote:
| Two words: Hotwire Native
| grounder wrote:
| I'll look this up later tonight. Is Hotwire using the same
| approach as Capacitor / Ionic?
| hsavit1 wrote:
| So many of you are yapping about how the performance is not good
| enough. Yet none of you are talking about how Shopify literally
| could not develop their mobile app without it. The 3 minutes to
| compile the app just to do a trivial change makes it near
| impossible for devs to be productive. Hot reloading is what got
| me hooked to react native, I literally cannot allow for my brain
| to rot waiting for minutes waiting for Xcode to compile for a
| simple border radius change.
| morelish wrote:
| I've noticed the app has gotten a lot slower and buggier on iOS
| in the last few years. Kind of wondered what they were writing it
| with.
| sirjaz wrote:
| They could have written a MacOS and Windows app to go along with
| their web app with React Native but didn't. Such a missed
| opportunity
___________________________________________________________________
(page generated 2025-01-16 23:00 UTC)