In September 2026, Shopify Engineering published an article titled “Native is now the future of mobile at Shopify.”
https://shopify.engineering/back-to-native
This was significant news.
In 2020, Shopify announced that React Native would be the future of mobile development at the company. Shopify has also been a major contributor to the React Native ecosystem ever since.
Now, Shopify is moving back toward native development with Swift and Kotlin.
Unsurprisingly, this has led to reactions along the lines of “cross-platform development with React Native or Flutter doesn't work after all” or “native is the future.”
But that's not really what Shopify's article says.
To me, the article is a great opportunity to reconsider a more fundamental question:
What costs are we actually trying to reduce when we choose cross-platform development?
React Native and Flutter are just tools. If they help, use them. If the trade-off stops making sense, stop using them.
So how do we decide whether that trade-off makes sense?
Shopify isn't saying React Native was a failure
Let's establish this first, because it's important.
Shopify explicitly looks back at its decision to adopt React Native in 2020 as the right decision for the company at the time.
One of the problems Shopify wanted to solve was the cost of implementing the same feature twice for iOS and Android and then keeping those implementations in sync.
React Native made it easier to deliver a feature to both platforms from a single implementation. It also made mobile development more accessible to developers whose primary experience was on the web.
React Native came with costs of its own, of course: framework upgrades, boundaries between React Native and native code, dependencies on third-party libraries, performance considerations, and so on.
Those costs existed in 2020, too.
But the benefits of reducing the cost of maintaining two native applications outweighed them.
So React Native made sense.
In 2026, the equation changed.
Shopify has deeply integrated coding agents into its development process. Agents can use an implementation on one platform as a reference for implementing the other, while tests and review systems help maintain behavioral parity between the two.
Maintaining two native applications hasn't become free.
It has simply become cheaper than it was in 2020.
Meanwhile, the costs associated with React Native haven't disappeared.
The balance changed.
This isn't a story about React Native turning out to be bad.
It's a story about the cost structure behind a technology decision changing over time.
Technology doesn't make costs disappear
I've long thought that looking only at “what percentage of our code can we share?” is a poor way to evaluate cross-platform development.
Suppose you develop iOS and Android applications independently.
The obvious cost is implementation: you might have to write the same screen once in Swift and once in Kotlin.
But code isn't the only thing you duplicate.
You need to apply specification changes to both implementations, make sure their behavior stays consistent, and synchronize bug fixes.
The duplication can even extend beyond engineering.
If the UI and workflows differ between platforms, you may need separate support documentation. Customer support staff may need to learn both versions of the product.
On the other hand, adopting React Native or Flutter doesn't magically eliminate all of these problems.
You still have native APIs and OS updates to deal with. You now have a cross-platform framework to upgrade as well. And when an abstraction leaks, you may eventually find yourself debugging Swift or Kotlin anyway.
Technology doesn't magically delete costs.
A more useful mental model is:
Technology moves costs from one place to another.
What can cross-platform development make cheaper?
Implementation cost
This is the most obvious one.
Instead of implementing the same business logic or UI independently for iOS and Android, you can implement it once as shared code.
This is also an area where coding agents are particularly effective.
If an agent can take an iOS implementation and produce the corresponding Android implementation, the relative advantage of sharing the code itself becomes smaller.
But reducing the cost of producing code is not the same as reducing the cost of maintaining that code.
Synchronization cost
For some projects, I think this is even more important than implementation cost.
When you have two codebases, you need to continuously maintain the condition that they implement the same specification.
A feature or bug fix can accidentally land on only one platform. Two developers can interpret the same requirement slightly differently.
If the relevant code is shared, this class of problem becomes much smaller within the shared portion.
Shopify shows us another way to reduce this cost.
If you can combine coding agents, tests, reviews, and development infrastructure to maintain parity between two implementations, synchronization can become cheaper even without shared application code.
But the important point is that simply introducing a coding agent does not make synchronization costs disappear.
Shopify isn't just asking an agent to write code.
It has invested in checkpoints, tests, visual review, multiple layers of code review, human approval, and the surrounding infrastructure required to make this development model work.
There's still quite a distance between “Shopify can do this” and “we can start doing this tomorrow.”
Quality assurance cost
Sharing business logic can also affect QA costs.
This does not mean that using React Native or Flutter lets you test only one platform.
UI behavior, operating system APIs, application lifecycle differences, device-specific behavior, and many other things still need to be verified separately on iOS and Android.
But imagine that exactly the same business logic is running on both platforms.
In that situation, you may be more comfortable saying:
We've already tested this calculation thoroughly on iOS. Given that Android executes the exact same implementation, we'll reduce the number of equivalent cases we repeat there.
When QA resources are limited, that can allow you to spend more of your time on platform-specific behavior instead of repeating tests against identical shared logic.
With two native implementations, the situation is different.
Even if both implementations follow the same specification, they are still different code. You need stronger evidence before assuming that QA results from one implementation also tell you something about the other.
Shared code doesn't eliminate QA.
But “this is literally the same implementation” can sometimes be a useful reason to reduce duplicated testing.
Shopify isn't ignoring this problem either.
Once you have two implementations, coding agents can introduce different bugs into the iOS and Android versions. This is one reason Shopify has invested in tests, visual review, parity checks, and other mechanisms for detecting differences between the implementations.
In other words, Shopify is also moving costs around.
The QA advantage you might get from shared implementation is replaced by investment in automation and development infrastructure that makes two implementations practical to verify.
Learning cost and context switching
Code isn't the only thing a cross-platform technology can share.
Consider a slightly unusual React Native architecture where the iOS and Android UI code is not shared at all:
- iOS: React Native UI written specifically for iOS
- Android: React Native UI written specifically for Android
If your KPI is code-sharing percentage, this might look like a failure.
But from the developer's perspective, it can still be valuable.
Both implementations use React's component model. Developers manage state and asynchronous operations in familiar ways. Styling follows the same general programming model.
When an iOS developer helps with the Android implementation, they don't have to switch their entire mental model from SwiftUI to Jetpack Compose.
They can bring their React knowledge with them.
What you're sharing here isn't source code.
You're sharing developer knowledge.
That means there can be value in sharing a development model even when you don't share the application code itself.
As an aside, I remember Microsoft Office using React Native in something close to this style.
When I looked into it again while writing this article, I was able to confirm that Office has combined shared C++ logic with React Native. However, I couldn't find a primary source confirming my specific memory that reducing developer context switching was an explicit motivation.
So take that particular historical detail with a grain of salt. I may be remembering it incorrectly.
The architectural pattern itself is still useful for thinking about what “sharing” can mean.
Hiring and organizational cost
Imagine a company with ten web developers who know React well, but almost nobody with significant Swift or Kotlin experience.
React Native has a very different value to that organization than it does to a company with strong, well-staffed iOS and Android teams.
Choosing native development might mean hiring specialists, training existing developers, or asking people to learn an additional technology stack.
If you split development into dedicated iOS and Android teams, you also introduce communication and scheduling costs between those teams.
Cross-platform development doesn't eliminate these costs.
But it can move the boundaries of where specialized expertise is required.
Costs cross-platform development doesn't solve
Even if you adopt React Native or Flutter, the App Store and Google Play are still separate platforms.
Signing, review processes, and distribution differ.
Push notifications, deep links, permissions, background execution, and many other capabilities still depend on platform-specific behavior.
Some bugs only appear on real devices. OS updates can suddenly change behavior.
Having one codebase does not mean you have one mobile application.
Your users are still running an iOS application and an Android application.
Testing, release management, store operations, and platform-specific quality assurance remain.
If you estimate that “half the code means half the development cost,” you're probably going to have a bad time.
Costs introduced by cross-platform development
Cross-platform technologies also introduce costs of their own.
With React Native, React Native itself sits between your application and the operating system.
With Flutter, Flutter does.
When the abstraction works well, that's extremely useful.
But when you encounter platform-specific functionality, performance problems, or framework bugs, you may need to cross that abstraction boundary.
You also need to keep the framework and its dependencies up to date.
So in exchange for reducing the cost of maintaining two native implementations, you accept the cost of maintaining an additional cross-platform abstraction layer.
That doesn't make React Native or Flutter bad.
Useful abstractions have maintenance costs.
The question is what becomes cheaper in exchange for paying them.
Coding agents move the balance
Let's return to Shopify.
Coding agents clearly make it cheaper to implement the same feature twice in Swift and Kotlin.
An agent can use one implementation as a reference for generating the other. Developers can also use agents to work in languages and frameworks they don't use every day.
That reduces some of the advantages traditionally associated with cross-platform development.
But generating the code twice doesn't guarantee that the two implementations will remain behaviorally identical.
Someone still needs to review the generated code.
Someone still needs to maintain it several years later.
Someone still needs to investigate platform-specific bugs.
And values such as sharing developer knowledge or making engineers more portable across teams aren't fully captured by the cost of code generation.
Shopify has built development infrastructure for returning to native, and presumably has grown an organization capable of absorbing the costs that come with it.
Is your organization in the same position?
Don't ask which technology is “right.” Ask what you're trying to make cheaper.
Cross-platform development has always attracted its share of technology arguments.
Native is better.
React Native lets us ship faster.
Flutter lets us build everything once.
You'll end up writing native code anyway.
Depending on the circumstances, all of these statements can be true.
But technology selection isn't really about deciding which statement is universally correct.
The useful questions are:
Where is your product and organization spending the most time and money today?
Which costs are you trying to reduce?
And where are you willing to move those costs instead?
React Native was a reasonable choice for Shopify in 2020.
In 2026, coding agents and Shopify's development infrastructure changed the equation enough that native development became the more reasonable choice for Shopify.
That doesn't mean “the React Native era is over.”
It means Shopify's optimal choice changed.
Other organizations may reach different conclusions.
They have different team sizes, different skills, different products, different UI requirements, and different costs they are willing or able to absorb.
React Native, Flutter, Swift, and Kotlin are all just tools.
Instead of importing the conclusion reached by a famous company, figure out which costs your own organization is trying to reduce — and use the tools that help you do that.
Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.