Skip to content
useffect.sh
Book 30 min with a senior
Tooling

Prebuild (Continuous Native Generation)

The Expo command that generates the android and ios folders from app.json and config plugins instead of maintaining them by hand.

Definition

Prebuild is the Expo command (npx expo prebuild) that generates the native android and ios projects from a template matching your SDK version, then applies your app.json configuration and your config plugins on top. It is Expo’s implementation of a broader principle, Continuous Native Generation (CNG): native projects are short-lived artifacts, produced when needed (build, debug) and regenerable at any time, with configuration as the source of truth. Prebuild replaces hand-maintaining files such as Info.plist, AndroidManifest.xml, or the Podfile, and the painful merges on every React Native upgrade. In a project using it, android and ios are in .gitignore, and EAS Build runs prebuild automatically when those folders are absent. An ios folder missing from the repository but present on disk after a build is its signature, as is a plugins array in app.json listing config plugins.

In a real app

The command to know is npx expo prebuild --clean: it deletes the existing native folders before regenerating, which the docs recommend as the safest option. Without --clean, prebuild tries to merge with what is there, and a forgotten manual edit can survive or break things. --platform ios limits it to one platform, --no-install skips dependency installation. npx expo run:ios and run:android run prebuild on their own when the folders are missing, then reuse them as-is.

The classic pitfall: someone edits ios/Podfile or AndroidManifest.xml directly to unblock a build, it works, and six weeks later a prebuild --clean or an EAS build wipes the change. Every native change has to live in app.json or in a config plugin, including SDK version settings through expo-build-properties. If the native folders are committed, that has to be a deliberate, documented decision, because EAS Build then stops regenerating anything.

In an audit I check whether android and ios are git-ignored, whether prebuild --clean runs without errors on a fresh clone, and whether the diff between the generated project and the committed one is empty. A non-empty diff is a list of uncaptured native changes that need to become plugins.

Our services on this

Sources

All 35 glossary terms

One of these is blocking your app?

30 minutes with a senior to look at the problem in your code. Free.