[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)