What Shopify’s Return to Native Means for Agent-Driven App Architecture

On September 10, Shopify announced that its mobile development is moving from React Native back to Swift and Kotlin. Most of the discussion focused on the familiar native-versus-cross-platform debate. The more consequential part of Shopify’s post, however, was its account of how coding agents changed the cost model.
An agent may edit the code in seconds, then spend minutes controlling a simulator, reading the accessibility tree, taking screenshots, and deciding whether the change worked. Once code generation becomes fast, the bottleneck moves:
“It doesn’t matter how good the model is if it can’t test its work quickly.”
That observation matches what I have encountered while building Agenaxy, a local-first agent workbench for macOS. Modularity used to be justified mainly by maintainability, team boundaries, and code reuse. It now has another practical purpose: letting an agent find out, quickly and reliably, whether it broke the product.
The short version: an app built for agent-driven development needs an independently runnable core, stable machine-operable interfaces, fast core tests, real-app E2E coverage, and controllable substitutes for expensive or unreliable external dependencies.
When code gets cheap, feedback determines delivery speed
The cost of an implementation loop has never been limited to typing code:
Understand → edit → start the environment → prepare state
→ operate the product → observe → decide whether it is correct
Models compress the editing step first. Everything around it remains, and therefore becomes more visible.
This is especially pronounced in mobile and desktop apps. A web service can often be called directly and checked through logs and responses. An app usually has to be launched, navigated into the right state, and operated through a simulator or a real window. If an agent can only inspect screenshots, guess coordinates, or repeatedly parse a large accessibility tree, both feedback speed and reliability degrade quickly.
The useful metric is no longer how many lines an agent can generate per minute. It is the time from a code change to a trustworthy verdict: how much of that path can run without a person, and whether a failure leaves enough evidence for the agent to continue diagnosing it.
Shopify’s new evaluation sits inside this changed cost model. In 2020, sharing an implementation through React Native significantly reduced the cost of building and aligning two mobile apps. Now an agent can use an iOS implementation to help produce its Android counterpart, or the reverse. The relative value of shared implementation falls while native platform capabilities, first-party tools, and fewer abstraction layers regain weight.
React Native did not suddenly become worse. The share of total cost represented by “write the same feature twice” changed.
An app must be operable by both people and agents
Shopify’s response is direct: separate business logic from the UI, let the application core run headlessly on a desktop, and expose state, actions, and navigation to agents through a CLI. When simulator verification is necessary, the same command surface can connect to the real UI and reduce dependence on screenshots or an accessibility tree.
The CLI is more than a convenient input method. It implies an architectural contract. Core capabilities need a path independent of the interface; system state must be readable without visual inference; and business actions need stable semantics.
This is not a new idea. Hexagonal Architecture argued that an application should be drivable through different adapters: a graphical interface, automated tests, batch jobs, or other applications. Agents turn that principle from an occasional testing convenience into a frequently used production capability.
“Build the CLI or SDK first, then wrap it in a UI” is best understood as a dependency direction, not a mandatory project schedule:
CLI, automated tests, desktop UI, mobile UI
↓ depend on
stable command/query contracts
↓ access
business state and behavior
The UI still determines whether the product is usable. It simply stops being the only place where business capability exists or business truth can be observed.
The UI is a projection of facts—and the human control plane
In Agenaxy, the Engine owns execution, permissions, state transitions, and the event record. The Workbench UI projects those facts and translates human actions into commands. The UI may own interaction details such as an unfinished input draft, scroll position, or whether a panel is open. Whether a task is running, an approval took effect, or an operation finished must come from the Engine.
That boundary solves two problems at once.
First, the core can be tested without the interface. Complex flows become explicit states and signals; external calls are concentrated at execution boundaries. An agent can enumerate state combinations, run actions, and inspect results without launching the entire desktop app for every business rule.
Second, the UI does not quietly grow a second source of business truth. Frontends often infer a local state for responsiveness while the backend maintains the real one. The split may look harmless on the happy path, then diverge during recovery, cancellation, background work, or interruption. A UI that consumes fact projections reduces the number of state sources an agent must understand and modify.
Shopify and Agenaxy use the same two-layer principle here: core logic can be tested headlessly, and the complete app also has automated E2E coverage. Core tests give business rules a fast feedback loop. E2E tests cover real interaction and the full application boundary.
A testable core does not eliminate real UI testing
Passing business tests only shows that the core rules are probably correct. The product also contains the built frontend, windows, process communication, native system capabilities, and real input/output paths. A button may call the wrong command. A state change may fail to render. File pickers or the clipboard may break only in the packaged environment. A valid control may be obscured by the layout.
That is why Agenaxy also has E2E coverage through the real Tauri shell. An agent can launch the complete app, read a compressed semantic representation of the interface, click or type into exact elements, select files, scroll, wait for state changes, and capture screenshots when evidence is needed. The path crosses the Tauri Shell, Workbench, inter-process communication, and Engine lifecycle—the same boundary a user crosses.
The evidence is split into three layers:
- UI semantics answer: what can the user see and operate now?
- Normalized Engine facts answer: what did the system actually execute?
- Screenshots reveal layout, occlusion, styling, and other visual issues, while preserving the scene of a failure.
The first two layers are suitable for stable automated comparison. Screenshots vary with fonts, windows, animation, and system controls, so Agenaxy uses them mainly for failure evidence and visual review rather than pretending they are a perfectly stable pixel-level oracle.
The resulting testing rule is simple: verify business rules at the core layer whenever possible, then return to the complete app for interaction and visual behavior. Both layers matter; they run at different frequencies and answer different questions.
MockServer controls the cost of external dependencies
Even with automated core and UI tests, external dependencies can make the feedback loop slow, expensive, and difficult to diagnose.
Agenaxy connects to multiple model providers. Calling a live model during every regression run costs money and time, and its output varies. Network conditions, account limits, and provider incidents can turn a failure into an attribution puzzle: did our code break, or is the upstream service unstable today?
We use MockServer’s record-and-replay capability to capture an HTTP/SSE exchange through the provider’s real official endpoint, remove sensitive data, and store it as a reviewable fixture. Later runs replay the response offline while still exercising the real SDK, parser, application logic, and desktop path.
Our boundary is: replay model responses; execute tools for real.
The model’s next response can be fixed, but local actions—reading files, searching, and modifying content—still happen. This preserves a repeatable end-to-end agent sequence without replacing the business execution with a test-only fake.
Record and replay also makes change comparison easier. An agent can modify context assembly, the tool protocol, or the interface and replay the same upstream output. If the behavior changes, the upstream input did not move at the same time.
The same architecture extends naturally to IoT
Hardware is another external dependency—often harder to obtain, parallelize, and force into a failure state than a model API.
An IoT app handles business states that unfold over time: connection, command, acknowledgement, status report, disconnect, reconnect, and synchronization. Real devices remain essential, but if every code change requires one to be present, an agent cannot sustain an autonomous feedback loop.
The answer is a controllable scenario environment at the device communication boundary. A few fixed return values are not enough. The simulator needs state that changes after operations, delayed reports, timeouts, disconnections, and out-of-order messages. The agent can then start a scenario without hardware, operate the app, read its state, and inspect the interface.
The implementation depends on the protocol. HTTP paths can use a MockServer or recorded responses. MQTT can use a test broker. Bluetooth and serial protocols are better simulated at the protocol-adapter layer. Real-device sessions remain the final calibration step for radio behavior, power, OS permissions, firmware differences, and other properties software cannot reproduce completely.
Consider a firmware update that disconnects at 60%, reconnects, synchronizes state, and resumes from the checkpoint. An HTTP MockServer can supply version metadata and error responses. A device simulator, connected through the Bluetooth or serial adapter, can report power, firmware version, acknowledgements, and progress. The app’s reconnect, idempotency, and resume behavior becomes repeatable without a physical device.
Model services and IoT devices seem far apart, but they ask the same architectural question: can the external world be replaced with a controllable environment without replacing the application core or its real execution path?
The shared layer may move from code to intent
Shopify’s post contains one more signal worth extending. Its teams found that an agent can use one platform’s implementation to help build the other while shared specifications, tests, and review checkpoints preserve feature alignment.
Over time, the cross-platform “shared layer” may move upward:
Before: shared implementation → iOS + Android
Next: shared specification / behavior / tests
→ agent → Swift + Kotlin
I think of this as a shift from shared code to shared intent. “Intent” is not a vague product request. It is a specification that can constrain implementation: which actions are allowed in each state, how success and failure appear, which side effects must stop after cancellation, and which results must remain consistent across platforms.
Each platform can use its native capabilities fully. Shared assets describe what must remain consistent. Agents perform implementation and translation. People decide at review checkpoints whether the result is acceptable.
Shared code will not disappear. Business models, protocol definitions, and naturally portable modules remain worth sharing. The change is that one implementation is no longer the only way to preserve platform consistency. As generation and migration become cheaper, specifications, behavior tests, and review standards gain value.
This also creates a governance risk. If the same agent changes the specification, implementation, and tests at once, an error can be made internally consistent and promoted as the new truth. Tests are a source of truth only when they express confirmed business intent, and changes to those tests receive independent scrutiny.
Build a shorter path from change to evidence
For an app intended to be developed with agents, start with five questions:
- Can the business core run without the UI, cloud service, or real device?
- Can an agent read state, perform actions, and understand a failure precisely?
- Can external dependencies switch between real and controllable environments?
- After core tests pass, can the agent enter the real app to verify interaction and visuals?
- Is cross-platform consistency carried by specifications and behavior tests as well as implementation code?
Performance, bundle size, developer experience, and code reuse still matter. Agent-driven development adds three more architectural measures: feedback time, the share of behavior that can be verified autonomously, and the frequency of human intervention.
Code generation will keep getting faster. Architecture has to make observation, judgment, and verification keep pace.
These ideas continue to be tested in the development of Agenaxy, the local-first AI agent workbench I am building for macOS. If you are working on agent-driven development or application architecture, I would be glad to compare notes.