The Great Unwind
When Frameworks Stop Making Sense
When Frameworks Stop Making Sense
In a steam-powered factory, the layout followed the power supply. An engine turned an overhead shaft the length of the building, with belts carrying power down to the machines. The work had to fit around the machinery that powered it.

Early electrification kept much of that arrangement, with motors replacing steam engines but driving the same shafts. Giving each machine its own motor opened up a much bigger opportunity: the belts could come down, and factories could arrange the floor around the work instead of the power supply.
A layout that had seemed inevitable turned out to depend on a constraint that no longer applied.
Software is full of arrangements like that.
In 2020, Shopify bet on React Native: write a feature once, ship it on both platforms, spend less time chasing parity. It worked for six years. On September 10, 2026, Shopify announced its return to native.
Shopify’s agents could use an existing app as a reference to implement features in Swift and Kotlin, wire up data, and refine layouts from visual feedback. Engineers set direction and reviewed the results, but no longer had to write every platform’s implementation themselves. A core team of six, joined midway by feature teams, rebuilt the Shop app in twelve weeks.
The comparison below shows what users got back: faster launches on both platforms, a smaller Android download, and fewer sessions ending in a crash.
less time to openAndroid cold start
smaller appAndroid app size
fewer crashes1Sessions that crash
| Shop app | React Native | Native | Change |
|---|---|---|---|
| Android cold start | 4,433 ms | 2,233 ms | −50% |
| Android app size | 293 MB | 184 MB | −109 MB |
| Session stability | 99.5%+ | 99.95%+ | 10× fewer crashes¹ |
| iOS cold start | 3,200 ms | 2,466 ms | −23% |
| iOS app size | 67 MB | 68 MB | +1 MB |
These releases also included product simplifications, so the gains cannot all be assigned to removing a framework. But an architectural choice defended mainly by you’d have to write it twice becomes harder to justify as agents reduce that extra work. Maintaining two apps can still cost more. For a large user base, though, faster launches and fewer crashes pay off across millions of sessions, potentially outweighing the remaining engineering overhead.
Shared code also helps keep one product coherent across two platforms, so teams don’t have to interpret every change separately. Security, correctness, interoperability, and domain knowledge remain worth sharing. If we separate the implementations, we still need a shared definition of how the product should behave.
What if we shared the behavioral contract instead of sharing the implementation?
The contract spells out the promises users rely on: a saved item survives a restart, a failed payment leaves the cart intact, and an offline save syncs when the connection returns. Those promises should hold regardless of which language, framework, or team sits behind the app.
In MirrorCode, a benchmark from Epoch AI and METR, models rebuild programs without source access. The best rebuilds of gotree, a command-line biology toolkit, passed 2,000 of 2,001 checks against the original.
checks passed in a gotree rebuild
gotree cut dateBoundary mismatchEach square above represents one check. The amber square marks the one test that failed: a date cutoff exactly matching an existing node’s date produced an extra root node. That single difference matters to anyone relying on the original behavior, and even a perfect score would only cover the inputs tested.
For a mobile migration, the previous app’s behavior is the contract, except where the team deliberately chooses to change it. You should be able to run the same journeys through both apps from equivalent account, data, and permission states. Visually compare screens, content, and interactions, then check persisted data, API effects, and analytics events. Review execution traces and performance profiles for errors, bottlenecks, and unnecessary work. The rewrite needs evidence that the product survived the change in code.
For a greenfield product, there’s no previous app to compare against, so you need to specify the expected screens, states, and transitions up front.
Keep those expectations under version control so an agent can use the visual evidence to fix a regression, rerun the same journey, and continue once the expected behavior is restored.
The same agents that make sweeping code changes possible can help verify them. The recording below shows a swarm exploring different paths through an app in parallel on cloud devices, returning visual evidence in live reports. Applied to both implementations, that exploration can help uncover differences for the team to investigate.

The captured screens become more useful when you can see how a user moves between them. In the Atlas recording below, screens form a map connected by the actions agents took. Teams and coding agents can query that shared reference to understand how the app behaves and what a replacement must preserve.
After the rewrite, each PR can make that reference more useful, showing what changed for the user, what still works, and which differences were intended. Atlas automatically connects the visual evidence to the relevant screens and journeys. Verified behavior becomes a durable asset, growing more valuable as the code around it gets easier to replace.
In the illustration below, evidence from successive PRs expands the map while staying attached to the same screen identities. The highlighted screen gains new evidence without becoming a new node each time.
Native back navigation, permissions, and share sheets may still need to follow each platform’s conventions. A shared contract needs to allow for those differences and keep unexplored paths distinct from verified behavior.
Two implementations still need maintenance, and no single migration can establish that native is cheaper for every team. But a behavioral contract lets you change the stack without rediscovering the product, so a framework stays a choice you can revisit.
Electricity let factories arrange the floor around the work. As agents reduce the cost of building twice, software teams gain more freedom to choose an architecture around the user. Two implementations may still take more work today, but the bet is that agents keep shrinking that overhead while faster launches and fewer crashes keep paying users back.
Users never asked for a particular architecture. They asked for an app that opens quickly, remembers their work, and behaves the way they expect. The point of cheaper code is to stop charging them for the compromises we made to produce it.
That bill is refundable.