The core plugin system provides the foundational functionality for creating, composing, and executing configuration plugins in @expo/config-plugins. It handles plugin resolution, execution order, error handling, and caching.
Apply multiple plugins to a configuration in sequence.
function withPlugins(
config: ExpoConfig,
plugins: (StaticPlugin | ConfigPlugin | string)[]
): ExpoConfig;Parameters:
config: The Expo configuration object to modifyplugins: Array of plugins to apply, can be plugin functions, static plugin tuples, or module pathsUsage:
const config = withPlugins(baseConfig, [
withCustomFeature,
["@expo/config-plugins", { option: "value" }],
"./local-plugin"
]);Apply a single static plugin with automatic resolution and error handling.
function withStaticPlugin(
config: ExpoConfig,
options: { plugin: StaticPlugin | ConfigPlugin | string }
): ExpoConfig;Parameters:
config: The Expo configuration object to modifyoptions.plugin: The plugin to apply - can be a function, static tuple, or module pathCreate a plugin wrapper that ensures the plugin only executes once based on a cache key.
function createRunOncePlugin<T>(
plugin: ConfigPlugin<T>,
name: string
): ConfigPlugin<T>;Parameters:
plugin: The plugin function to wrapname: Unique identifier for cachingUsage:
const withOnceOnlyFeature = createRunOncePlugin(
(config) => {
// Plugin logic here
return config;
},
"withOnceOnlyFeature"
);Apply a plugin only once based on a cache key, with manual cache control.
function withRunOnce(
config: ExpoConfig,
options: { plugin: ConfigPlugin; name: string }
): ExpoConfig;Parameters:
config: The Expo configuration objectoptions.plugin: The plugin function to applyoptions.name: Cache key for run-once behaviorCustom error class for plugin-related errors with enhanced debugging information.
class PluginError extends Error {
constructor(message: string, cause?: string);
}Usage:
if (invalidConfig) {
throw new PluginError(
"Invalid configuration detected",
"The plugin requires a valid API key"
);
}type ConfigPlugin<Props = void> = (config: ExpoConfig, props: Props) => ExpoConfig;
type StaticPlugin<T = any> = [string | ConfigPlugin<T>, T];
type PluginParameters<T extends ConfigPlugin<any>> = T extends (
config: any,
props: infer P
) => any
? P
: never;import { ConfigPlugin } from "@expo/config-plugins";
const withCustomSetup: ConfigPlugin<{ apiKey: string }> = (config, { apiKey }) => {
if (!apiKey) {
throw new Error("API key is required");
}
// Apply modifications to config
return config;
};import { withPlugins, createRunOncePlugin } from "@expo/config-plugins";
const withComplexFeature = createRunOncePlugin((config) => {
return withPlugins(config, [
withAndroidSetup,
withiOSSetup,
["@expo/config-plugins", { feature: "enabled" }]
]);
}, "withComplexFeature");const withConditionalFeature: ConfigPlugin<{ enableFeature?: boolean }> = (
config,
{ enableFeature = false } = {}
) => {
if (!enableFeature) {
return config;
}
return withPlugins(config, [
withFeatureSetup,
withFeatureConfiguration
]);
};