~/wellseasoned.dev

Death of the Middleware

· 3 min read

I was three days into fighting React Native when I made a decision that shouldn’t have made sense: start over.

I had a working iOS app that did what I wanted, but I was working on adding some features specific to iCloud and kept running into rough edges. The kind of thing you’d normally push through on: fix the bugs, work around the bridge performance issues1, wait for the framework to catch up to iOS features. Standard React Native development.

Instead, I opened Claude, fed it the codebase, and asked it to extract the specification. What does this app actually do? What are the features, the flows, the business logic, the existing test harness? Then I asked it to reimplement everything in Swift.

Two hours later, I had a native iOS app. It wasn’t perfect, I found that a lot of the UI tweaks I had sorted with the old app were lost… but I had claude extract a set of wireframes and rebuild the app with them as a part of the spec.

What really struck me was that the entire value proposition of React Native for this project went from net positive to net negative.

The Changing Economics of Abstractions

Cross-platform frameworks solve a real problem: maintaining multiple codebases is expensive. Building the same feature in Swift for iOS, Kotlin for Android, and TypeScript for web means building it three times. React Native offered a trade—write once in JavaScript, accept overhead and complexity, get three platforms for roughly 1.5x the cost of one2.

That math worked when human coding time was the bottleneck.

The abstraction tax was real: leaky behavior, performance overhead3, ecosystem lag, occasional framework battles. But it beat paying three teams to build three apps. The middleman earned its keep by reducing code humans had to write.

What Happens When Code Gets Cheap

AI code generation inverts the economics.

When I can take a specification and generate a Swift implementation in hours, then generate a Kotlin implementation from the same spec the next day, the abstraction layer stops being a cost saver. It becomes pure overhead.

The marginal cost of an additional platform drops toward zero. I’m not maintaining three codebases—I’m maintaining one specification and regenerating implementations as needed.

Each implementation can be idiomatic to its platform. No lowest-common-denominator APIs. No “this works on iOS but React Native doesn’t expose it yet.” No debugging JavaScript bridge performance.

The specification becomes the source of truth. Code becomes a build artifact.


Footnotes

  1. React Native’s bridge architecture has well-documented performance overhead due to asynchronous communication between JavaScript and native code. The New Architecture (introduced in 2022-2023) addresses some of these issues through JSI (JavaScript Interface), but migration remains gradual. Sources: React Native Documentation: The New Architecture, Meta Engineering Blog

  2. Cross-platform development cost estimates vary, but industry analyses typically cite 30-40% cost savings over native development for both platforms. The “1.5x” figure represents a rough approximation balancing reduced code duplication against framework overhead and platform-specific customization. Sources: Surf: React Native vs Native Apps Cost, Codebridge: React Native App Development Cost

  3. React Native performance trade-offs are well-documented: the JavaScript bridge introduces latency, memory overhead from dual runtimes, and challenges with complex animations or heavy data processing. These are inherent architectural trade-offs, not bugs. Sources: React Native Performance Overview, Shopify Engineering: React Native Performance