Plugin execution flow
When you runnpx expo prebuild, the following sequence occurs:
Expo CLI reads your app.json or app.config.js file and evaluates all JavaScript code to produce a complete ExpoConfig object.
All plugins listed in the plugins array are resolved:
app.json
- Strings are resolved as npm packages or file paths using
require() - Functions are used directly
- Arrays contain
[plugin, props]where plugin is resolved and props are passed as the second argument
withPlugins.ts
mod-compiler.ts
Info.plist, AndroidManifest.xml, build.gradle, etc.
The native ios/ and android/ directories are created using templates. If they already exist and --clean is used, they’re deleted first.
All registered mods are sorted and executed in a specific order:
mod-compiler.ts
dangerousmods run first (before any file is loaded)- Core mods like
xcodeprojrun early (many plugins depend on them) - Regular mods run in the middle
finalizedmods run last (after all modifications)
- XML files (AndroidManifest, strings.xml) are serialized back to XML
- Plist files (Info.plist, .entitlements) are written as XML plists
- Text files (Gradle, Podfile, Java) are written as strings
- Xcode projects are serialized using the
xcodenpm package
ios/ and android/ directories now contain fully configured native projects ready to build.
The mods system
Mods (modifications) are the core mechanism for changing native files. Each mod corresponds to a specific file or group of files.How mods work
A mod is a function that receives file contents, modifies them, and returns the result:Plugin.types.ts
ExportedConfigWithProps includes:
Mod types
Provider mods (isProvider: true)
These read files from disk and provide them to child mods:
Modifying native projects
iOS example: Adding to Info.plist
Android example: Adding permissions
Permissions.ts
The plugin chain in detail
Let’s trace a complete example:app.config.js
Introspection mode
Plugins can be run in “introspection mode” to read config without modifying files:mod-compiler.ts
- EAS Build to extract native configuration
- Expo CLI to validate config
- Testing and debugging tools
Error handling
Plugins can throwPluginError for better error messages:
errors.ts
MODULE_NOT_FOUND: Plugin package not foundCONFLICTING_PROVIDER: Multiple providers for same modINVALID_MOD_ORDER: Provider must be lastMISSING_PROVIDER: No provider for modINVALID_PLUGIN_TYPE: Invalid plugin format
Debug mode
Enable debug logging to see the plugin chain:withMod.ts