Why AI Code Generation Needs Expo, Not Bare React Native

RI

By Riya

30th Aug 2026

Last updated: 30th Aug 2026

Why AI Code Generation Needs Expo, Not Bare React Native

An LLM that writes mobile app code breaks bare React Native in ways a human developer would not. Not because the code is worse — often it is fine — but because the rest of the pipeline around bare React Native was designed for a human who runs Xcode, edits Podfile, restarts Metro when it hangs, and knows why pod install failed. An AI code generator doesn't. It writes files and waits for the preview to reload.

That mismatch is the reason RapidNative — an AI mobile app builder that generates React Native and Expo code from natural language — is 100% Expo across every template it ships. There is no bare React Native option. It isn't a religious preference; it's what happens when you write down the constraints an AI code generator puts on its host framework, and then look for the only mobile stack that satisfies them all.

This post is that list of constraints, and how Expo answers each one.

Mobile app development on a laptop and phone The AI generator side of the pipeline changes what "developer experience" means — Photo by Firmbee.com on Unsplash

The Expo vs React Native question, reframed

Most "Expo vs React Native" comparisons weigh the same axes: how much control you want over native code, whether you plan to add third-party SDKs that ship as native modules, and how tolerant you are of the extra dependencies Expo pulls in. Those are the right axes when the developer is a human.

When the developer is a large language model, the axes shift:

  • Latency between "file written" and "user sees change" matters more than build flexibility. Humans tolerate a 90-second rebuild once; an AI streaming code will trigger it fifteen times a minute.
  • Uniformity of the API surface matters more than expressive freedom. An LLM is only as reliable as the parts of the framework it saw enough of during training. A stack with two ways to do everything doubles the ways to fail.
  • The preview environment must run in a browser tab. Nobody is going to run Xcode Simulator to see if the generated LoginScreen.tsx centered the button.
  • Publishing must be a config file, not a build script. An AI can fill out eas.json; it cannot debug a broken CocoaPods lockfile.

Once you write those down, "bare React Native" isn't a peer of Expo — it's a stack that was never designed for a machine to drive. Expo, especially since Expo SDK 50 and the maturation of Expo Router, was.

The seven constraints an AI code generator puts on a mobile framework

Here are the constraints RapidNative's pipeline actually imposes, drawn from the real templates in the repo — fullstack-supabase, fullstack-v2, and nativewind-themed — and the system prompts the coding agent uses.

1. File-based routing so "add a screen" is one file, not five

When an AI adds a screen to an app, the simplest thing that can possibly work is: write one file at a predictable path, and have it show up in the navigator. That is exactly what Expo Router provides — the file tree under app/ is the navigation graph.

Bare React Native leans on React Navigation, which is excellent but not file-based. Adding a screen means editing a navigator config, registering a route name, and — if it's a dynamic route — wiring param types through the navigator's generic. Five files, four of which the model has to keep consistent, none of which are collocated. That's five places for a hallucinated route name to break something.

Every RapidNative template wires "main": "expo-router/entry" in mobile/package.json, ships Expo Router 6, and hard-codes the file-based convention into the system prompt. Look at the coding agent's routing rule:

"Wire the FULL chain: (1) navigate with router.push('/tickets/' + id); (2) read with useLocalSearchParams<{ ticketId: string }>(); (3) register <Stack.Screen name="tickets/[ticketId]" />."

That three-line rule replaces what would be a paragraph of navigator configuration on bare RN. The reduction in surface area is the point.

2. Instant on-device testing without a native build

A generated app needs to be testable on a real phone within seconds of the last code edit — otherwise the whole "prompt to app" promise collapses. Bare React Native's on-device story requires either a custom development client (a compiled binary you install first) or a full production build. Neither is compatible with "user prompts, iterates ten times, wants to hold the result in their hand."

Expo Go — the pre-built dev client on the App Store and Play Store — flips the model. The user scans a QR code, and the JavaScript bundle streams into the running app. No native build. No developer certificate. No xcodebuild in the pipeline.

That is why the RapidNative preview UI includes a QR code alongside the browser iframe. The QR points at an Expo Go-compatible bundle URL served by the sandbox. The code the AI just wrote is on a real device in under thirty seconds. Do that on bare React Native and you're waiting on a Fastlane run.

Person testing a mobile app on a phone Expo Go turns "test on real device" from a minutes-long build into a QR scan — Photo by Rob Hampson on Unsplash

3. Web preview from the same source, unmodified

The RapidNative editor lives in a browser tab. The preview is an iframe. Whatever code the LLM writes has to render in that iframe within a couple of hundred milliseconds — no native compile, no simulator boot.

That is only possible because Expo has invested in react-native-web and the Metro bundler's web target. RapidNative's editor takes it a step further with a package called browser-metro (a real dependency in package.json, version 1.0.35) that runs Metro inside the browser, and a companion project under tools/rapidnative-expo-router/ that is described in its own manifest as "a web-compatible wrapper around React Router that mirrors the expo-router API."

The web wrapper matters more than it sounds. The AI is generating one set of files. Those files import from expo-router. On device, expo-router runs natively. In the preview iframe, the wrapper resolves those same imports to a React Router-backed implementation with identical API shape. One codebase, two runtimes, zero platform forks in the generated app.

Do this on bare React Native and you either give up web preview or you make the AI generate two versions of every navigation call.

4. Managed native modules so the AI doesn't touch iOS or Android code

The single most dangerous thing an AI code generator can do is convince itself it needs to modify AppDelegate.swift or MainActivity.kt. It won't get it right often enough. Even when it does, the outcome is a project that only compiles on the user's machine after a pod install the user does not know how to run.

Expo's managed workflow puts a wall around native code. Camera, haptics, location, secure storage, sensors, audio — all of it is exposed as expo-* JavaScript packages that ship pre-built. The RapidNative system prompt is explicit about this:

"Prefer expo-* modules (expo-location, expo-haptics, expo-clipboard, expo-sensors, expo-av…) — they ship web support."

Two things the prompt is doing there: pushing the AI toward capabilities that don't require any native compile step, and ensuring the same capabilities render in the browser preview. expo-haptics is a no-op on web, not an error. expo-location uses navigator.geolocation. The AI does not have to know that. It just imports the same package.

On bare React Native, the equivalent is asking the AI to install a community package, follow platform-specific setup instructions, and hope autolinking picks it up. That is not a failure mode the model handles well.

5. A single, canonical way to style — NativeWind everywhere

If a framework offers three styling systems, the AI will pick a different one every third file. The way an AI code generator gets consistent output is by having exactly one blessed answer, everywhere.

All three RapidNative templates ship NativeWind 4 as a first-class dependency and the system prompt bans StyleSheet.create() outright. That's not because inline stylesheets are bad — it's because mixing them is bad, and the surest way to prevent mixing is to remove one of the options.

NativeWind exists comfortably in Expo because Expo's Metro config knows how to handle the Babel plugin and CSS pipeline in both native and web targets. On bare React Native, you're stitching together Metro config, Babel plugins, and web build configuration by hand — which the AI will do wrong at least once per project. Removing that failure mode was worth more than the flexibility to use styled-components on the odd screen.

6. Publishing that is a config file, not a build pipeline

A user who prompts an AI to build a fitness tracker eventually asks the AI to ship it. Publishing on bare React Native means Fastlane, provisioning profiles, App Store Connect API keys, xcodebuild archive scripts, and Android keystore management. None of it is code the model can write from a prompt.

Publishing on Expo means EAS Build and EAS Submit — a hosted build service configured by a single eas.json file. Credentials are managed by EAS. Builds run on Expo's infrastructure. Submission to the App Store and Play Store is one command. The AI can generate eas.json. It cannot generate a working Fastlane setup.

RapidNative's marketing surface reflects this directly: the comparison page calls out "Expo Launch handles App Store and Google Play submission" as the step after preview. That is only true because the framework choice makes it true.

7. Deterministic dependency versions across every generated project

Because every RapidNative template is pinned to the same Expo SDK, the same React Native, the same Expo Router, and the same NativeWind:

PackageVersion (all templates)
Expo54.0.13
React Native0.81.4
Expo Router6.0.12
NativeWind4.2.1
@expo/metro-runtime6.1.2

The generator only needs to know one universe. Every generated project starts identical; only user code differs. That means every bug the AI produces is reproducible, every fix generalizes, and the sandbox preview and on-device Expo Go share a bundle format. Bare React Native has no equivalent of this pinning story — the "correct" React Native version depends on which community CLI you used, which packages you installed, and when.

Code editor with structured project files Pinned versions across every template mean bugs are reproducible and fixes generalize — Photo by Ilya Pavlov on Unsplash

What we gave up

Honesty about tradeoffs, since this isn't a marketing page: choosing Expo does cost something.

  • Native modules that don't ship in the Expo SDK need a custom development client. For a bespoke Bluetooth peripheral or an old ObjC library, you leave the managed workflow. In the AI-generated world this comes up almost never — but when it does, the user has to eject to a custom dev client, which requires an EAS Build. That's a real step, not a free one.
  • Bundle size is bigger. Expo ships modules for capabilities you may not use. On the scale of "hello world," bare RN wins the disk-usage comparison. On the scale of "real app that also uses haptics, location, splash screen, secure storage, and status bar," the gap is minor and the developer-hours saved dominate.
  • You are betting on Expo's release cadence. Each SDK upgrade is a coordinated migration. When SDK 54 shipped, the templates moved together. If you were on your own it would be slower. In practice, Expo's cadence has been good and its upgrade tooling has been better than the community React Native equivalent.

None of these outweigh the constraints in the previous section, and all of them are things a human developer would also live with. But listing them matters — if the tradeoff analysis in your project points the other way, choose the other framework.

The internal pipeline, made concrete

To ground all of this: what actually happens when a user prompts "add a settings screen" inside RapidNative?

  1. The prompt goes to a multi-model routing layer that selects a coding-capable LLM based on the task. The model receives a system prompt that names Expo, Expo Router, and NativeWind as the target stack — it is not free to invent a different one.
  2. The model writes a file. On the current templates that file lands at app/settings.tsx. Expo Router picks it up as a route immediately; no navigator config edit is required.
  3. browser-metro, running inside the editor iframe, re-bundles the changed module. The rapidnative-expo-router web wrapper resolves the expo-router imports the model wrote to their web-runtime equivalents.
  4. A rn-preview-reload event fires. The iframe hot-reloads that one module. On the phone, Expo Go reloads the same module over the WebSocket dev channel.
  5. When the user is ready to publish, RapidNative's export packages the project — untouched, since it was already a valid Expo project on disk — and hands it to EAS Build. There is no transformation from "editor project" to "shippable project" because they are the same thing.

Every step of that pipeline benefits from the framework choice. Steps 2, 3, and 4 are impossible on bare React Native in a browser tab. Step 5 is possible but takes weeks longer to build and is fragile once built.

People Also Ask

Is Expo just a wrapper around React Native?

No. Expo includes React Native, but adds a set of pre-built native modules (expo-*), a file-based router (Expo Router), a hosted build service (EAS), and a preview client (Expo Go). For AI code generation the important piece is not the modules but the managed workflow — a boundary that keeps the AI out of iOS and Android native code.

Can you eject an Expo project to bare React Native?

Yes — Expo supports the "prebuild" flow which generates native ios/ and android/ directories from a managed project. Once you do this, you can install any React Native community package. RapidNative-generated projects can be prebuilt at any time; you don't lose the option, you just don't need it by default.

Why not use React Native CLI with individual Expo packages?

You can install expo-router and expo-camera in a bare React Native app. What you can't easily do is get the browser preview, EAS Build, Expo Go on-device testing, and the SDK pinning story. Those are workflow features, not package features. For a human that tradeoff is arguable. For an AI code generator it isn't.

The framework was the first decision — everything else followed

When we mapped out the AI-generation pipeline, the framework choice sat upstream of every other question: how the preview iframe would work, how on-device testing would work, how publishing would work, how the system prompt would be structured. Get that wrong and every downstream layer gets more expensive.

Expo made every downstream layer cheaper, and made a few of them possible at all. Bare React Native was a beautiful framework for the world it was built for. That world doesn't include an LLM in the developer chair. Ours does.

If you want to see what this actually looks like — one prompt, generated code, live preview, QR to your phone — try RapidNative. Or if you want to poke at the model directly by sketching an app instead of typing one, start from a whiteboard.

For more on the pipeline this framework choice enabled, see our writeups on how we built instant React Native preview without a build step and inside RapidNative's export pipeline from AI-generated code to the App Store.

Start now

Ready to build your app?

Turn your idea into a production-ready React Native app in minutes.

Free tools to get you started

Questions

Frequently asked questions

What is RapidNative?

RapidNative is an AI-powered mobile app builder. Describe the app you want in plain English and RapidNative generates real, production-ready React Native screens you can preview, edit, and publish to the App Store or Google Play.

Can I export the code?

Yes. RapidNative generates clean React Native and Expo code that you can export at any time. No lock-in, no proprietary format. Hand it to your developers or keep building inside RapidNative.

Is RapidNative free to use?

Yes. You can build apps on the free plan with no credit card required. Paid plans unlock unlimited AI generations, code export, and direct publishing to the App Store and Google Play.

Do I need to know how to code?

No. Most users build apps by describing what they want in plain English. Developers can drop into the code whenever they want more control, but coding is optional.

How long does it take to build an app?

Most users have a working first screen in under a minute. A full MVP usually takes a few hours instead of the weeks or months traditional development requires.