The Expo-versus-bare debate is mostly settled by modern Expo: with development builds and config plugins you keep almost all of Expo's tooling while still using arbitrary native code. The real question is who owns the native projects and how much custom native work the product needs.
Key takeaways
- Choose based on native requirements, release ownership, and team experience.
- Expo development builds support many products without giving up native code.
- Prefer the simplest workflow that still supports the app's long-term platform needs.
What actually differs now
A managed Expo project keeps the native ios and android directories generated, configured through app config and config plugins. A bare project commits those directories and you edit them directly. Development builds bridge the gap: you can add any native dependency to a managed project and still use Expo Go-style fast iteration through a custom dev client.
Because of this, "managed" no longer means "no native code." Most teams should start managed and only prebuild/eject to bare when a dependency genuinely cannot be expressed through a config plugin.
How to decide
Stay managed when you want EAS Build, OTA updates, and a small native maintenance surface, and when your native needs are covered by existing libraries and plugins. Go bare when you maintain a large custom native module, integrate an SDK with manual native setup, or need full control of the Gradle and Xcode build pipelines.
Whichever you pick, document the release process and keep the native configuration reproducible so a new engineer can build the app on day one.