An Expo team wants to commit ios and android and edit them directly instead of using Continuous Native Generation; how do you decide, and what does it cost?
answer
- who owns the native files
- app config native fields ignored
- EAS stops running prebuild
- upgrades become manual merges
- reversible: plugins, then regenerate
basics
~20 sCommit native folders only when needed native changes cannot reasonably be expressed as packages and config plugins. The cost is owning both native projects: manual SDK upgrades, app config native fields no longer applied, and drift nobody regenerates away.
solid answer
~40 sStart from what the native changes are. If they fit into packages, app config and a few local config plugins, CNG is cheaper for the life of the app. Committing `ios/` and `android/` makes sense for heavy or frequent native work, brownfield integration, or native code no plugin can reasonably express. The costs are specific. EAS Build no longer runs prebuild, so native fields in the app config, such as `ios.bundleIdentifier`, are ignored with a warning and the native files win. Config plugins stop applying unless someone runs prebuild, which would overwrite the hand edits. SDK upgrades become manual merges through the upgrade helper. The decision is reversible: move customisations into plugins, delete the folders and regenerate, so it can be revisited.
go deeper
Recall that committing ios and android means the team maintains those files, and that CNG regenerates them from config instead.
Explain what stops working when folders are committed: app config native fields, automatic plugin application, and regeneration-based upgrades.
Show the failure you would catch in review: a plugin or config change that silently does nothing, or a prebuild run that wipes committed edits.
Own the trade across the app's lifetime: native change frequency, team skills, upgrade cadence and the path back, and set a trigger to revisit it.
## What the decision really is The question is not "Expo or not". A project that commits its native folders still uses Expo modules, Expo CLI, EAS Build and EAS Update. The decision is **who owns the native project files**: - under **CNG**, the team owns the inputs (packages, app config, config plugins) and the files are regenerated; - **committed native folders** (often called the bare workflow) make the team own the files themselves. For the habit-tracking app, the question becomes: can every native change the roadmap needs be written as a package or a plugin at a cost the team accepts? ## Reasons to commit native folders - **Frequent, exploratory native work**: the team edits Swift and Kotlin daily, and wrapping each change in a plugin slows it down. - **Brownfield integration**: React Native is embedded in an existing native app, which CNG is not designed to manage. - **Native configuration no plugin can reasonably express**, or a library whose setup is too invasive to automate. - **Existing React Native CLI projects** with years of native customisation, where adopting CNG would mean rewriting all of it as plugins first. ## What it costs, concretely | Area | Under CNG | With committed folders | |---|---|---| | App config native fields (`ios.bundleIdentifier`, icons, permissions) | applied on every generation | **ignored** by EAS Build, which warns and uses the native files | | Config plugins | run on every generation | run only if someone runs prebuild, which rewrites the folders | | EAS Build | runs prebuild first | builds the uploaded folders as-is | | SDK upgrades | regenerate | merge template changes with the upgrade helper, `npx pod-install` | | Removing a library | delete package and plugin | also find and remove its native edits by hand | The second row is the trap teams hit first: after committing the folders, someone adds a plugin to the app config and nothing happens, because nothing runs it. Running `npx expo prebuild` to apply it would, on SDK 57, delete the committed folders and regenerate them without the hand edits, and the uncommitted-changes prompt is off by default. ## A decision procedure 1. **List the native changes** the app has and the ones the roadmap implies. 2. **Classify each**: covered by an existing package or plugin; needs a small local plugin; needs deep, frequently changing native code. 3. **Estimate the ongoing cost**: plugins to write and upgrade with each SDK, versus manual merges of two native projects each upgrade. 4. **Check team skills**: committed folders need people comfortable in Xcode and Gradle for every upgrade, not only for features. 5. **Decide per app, revisit per quarter**: the answer changes as the native surface grows or shrinks. ## Middle paths - **Stay on CNG with local plugins and local native modules**: most custom native code can live in a module directory that autolinking picks up, with a plugin for configuration. - **Generate, experiment, then fold back**: run prebuild, prototype a change in Xcode, then turn the working change into a plugin and regenerate. - **Commit temporarily** for a hard integration, with a written plan to move the edits into plugins afterwards. ## Going back is possible The move is reversible. Expo's adopt-prebuild guide describes the path: express each native customisation as app config or config plugins, delete the folders, run `npx expo prebuild` and compare the generated projects against the old ones until they match. How long that takes depends entirely on how much hand-written native change accumulated, which is the best argument for keeping the list short while the folders are committed. ## Signals the decision was wrong - Plugins are being written to reproduce edits that change weekly: the team probably needs committed folders. - Nobody has touched the committed native files in months, and upgrades are dreaded: the team probably wants CNG back. ## Guardrails if you do commit the folders - Remove native fields from the app config that no longer apply, so nobody edits a value that is silently ignored. - Document in the repository that prebuild must not be run, or run it only on a throwaway branch to compare output. - Keep a list of every native customisation and why it exists; it is the migration plan if the team ever returns to CNG.
- After committing ios, a developer changes ios.bundleIdentifier in app.json and the EAS build ignores it; why?When an `ios` directory is present, EAS Build does not run prebuild and uses the value in the native project, warning that the app config field is ignored. Change the bundle identifier in the Xcode project, or return to generated folders.
- How would you move a project with committed native folders back to Continuous Native Generation?Express each native customisation as app config or a config plugin, gitignore and delete `ios/` and `android/`, run `npx expo prebuild`, and diff the generated projects against the old ones until nothing important is missing. Then build and test both platforms.
- Does committing native folders mean giving up Expo modules and EAS?No. Expo modules, Expo CLI, EAS Build and EAS Update all support projects with committed native folders. What changes is that the team, not prebuild, maintains the native files.
saying these in an interview costs you the question
- Committing native folders means you can no longer use EAS Build
- App config native fields still apply after the folders are committed
- Once the folders are committed there is no way back to CNG
- Running prebuild on committed folders merges with hand edits safely
- Every native change forces you to leave CNG