@expo/config-plugins is a powerful TypeScript library that provides tools for generating native app code from a unified JavaScript interface through Expo config plugins. It enables manipulation of native iOS and Android project files using JavaScript-based configuration plugins and modifiers (mods), extending beyond the capabilities of static Expo configuration.
npm install @expo/config-pluginsimport {
withPlugins,
withAndroidManifest,
withInfoPlist,
AndroidConfig,
IOSConfig,
ConfigPlugin
} from "@expo/config-plugins";For CommonJS:
const {
withPlugins,
withAndroidManifest,
withInfoPlist,
AndroidConfig,
IOSConfig
} = require("@expo/config-plugins");Submodule imports:
import * as AndroidConfig from "@expo/config-plugins/build/android";
import * as IOSConfig from "@expo/config-plugins/build/ios";import {
withPlugins,
withAndroidManifest,
withInfoPlist,
ConfigPlugin,
AndroidConfig
} from "@expo/config-plugins";
// Create a config plugin
const withCustomConfig: ConfigPlugin = (config) => {
// Apply Android manifest modification
config = withAndroidManifest(config, async (config) => {
const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow(config.modResults);
AndroidConfig.Manifest.addMetaDataItemToMainApplication(
mainApplication,
"com.example.custom_key",
"custom_value"
);
return config;
});
// Apply iOS Info.plist modification
config = withInfoPlist(config, (config) => {
config.modResults.CustomKey = "CustomValue";
return config;
});
return config;
};
// Apply plugins to configuration
const config = withPlugins(baseConfig, [
withCustomConfig,
["@expo/config-plugins", { someOption: true }]
]);@expo/config-plugins is built around several key architectural components:
ConfigPlugin type and withPlugins orchestratorAndroidConfig) and iOS (IOSConfig)The foundational plugin system for creating and executing configuration plugins with proper composition and error handling.
type ConfigPlugin<Props = void> = (config: ExpoConfig, props: Props) => ExpoConfig;
function withPlugins(
config: ExpoConfig,
plugins: (StaticPlugin | ConfigPlugin | string)[]
): ExpoConfig;
function withStaticPlugin(
config: ExpoConfig,
options: { plugin: StaticPlugin | ConfigPlugin | string }
): ExpoConfig;
function createRunOncePlugin<T>(
plugin: ConfigPlugin<T>,
name: string
): ConfigPlugin<T>;The modifier system for making controlled changes to native project files with lifecycle management and introspection support.
function withMod<T>(
config: ExpoConfig,
options: { platform: ModPlatform; mod: string; action: Mod<T> }
): ExpoConfig;
function compileModsAsync(
config: ExportedConfigWithProps,
options: ModOptions
): Promise<ExportedConfigWithProps>;
function evalModsAsync(
config: ExportedConfigWithProps,
options: IntrospectionOptions
): Promise<ExportedConfigWithProps>;High-level plugins for modifying Android project files including manifest, resources, and build configuration.
function withAndroidManifest(
config: ExpoConfig,
action: Mod<AndroidManifest>
): ExpoConfig;
function withStringsXml(
config: ExpoConfig,
action: Mod<ResourceXML>
): ExpoConfig;
function withMainActivity(
config: ExpoConfig,
action: Mod<ApplicationProjectFile>
): ExpoConfig;
function withAppBuildGradle(
config: ExpoConfig,
action: Mod<GradleProjectFile>
): ExpoConfig;High-level plugins for modifying iOS project files including Info.plist, entitlements, and Xcode project configuration.
function withInfoPlist(
config: ExpoConfig,
action: Mod<InfoPlist>
): ExpoConfig;
function withEntitlementsPlist(
config: ExpoConfig,
action: Mod<Plist>
): ExpoConfig;
function withXcodeProject(
config: ExpoConfig,
action: Mod<XcodeProject>
): ExpoConfig;
function withAppDelegate(
config: ExpoConfig,
action: Mod<AppDelegateProjectFile>
): ExpoConfig;Comprehensive configuration utilities for Android platform including manifest manipulation, resource management, and build configuration.
namespace AndroidConfig {
namespace Manifest {
function getMainActivityOrThrow(manifest: AndroidManifest): ManifestActivity;
function addMetaDataItemToMainApplication(
mainApplication: any,
itemName: string,
itemValue: string,
itemType?: string
): any;
function readAndroidManifestAsync(projectRoot: string): Promise<AndroidManifest>;
}
namespace Permissions {
function getPermissions(manifest: AndroidManifest): string[];
function setPermissions(manifest: AndroidManifest, permissions: string[]): AndroidManifest;
}
}Comprehensive configuration utilities for iOS platform including Info.plist manipulation, entitlements, and Xcode project management.
namespace IOSConfig {
namespace Paths {
function getInfoPlistPath(projectRoot: string): string;
}
namespace Entitlements {
function getEntitlementsPath(projectRoot: string): string | null;
function setAssociatedDomains(
entitlements: Plist,
domains: string[]
): Plist;
}
}Essential utility modules for XML parsing, code generation, warning management, and history tracking.
namespace XML {
function parseXMLAsync(contents: string): Promise<any>;
function writeXMLAsync(options: { path: string; xml: any }): Promise<void>;
}
namespace CodeGenerator {
function mergeContents(options: MergeContentsOptions): MergeResults;
function removeContents(options: { src: string; tag: string }): MergeResults;
}
namespace WarningAggregator {
function addWarningIOS(property: string, message: string): void;
function addWarningAndroid(property: string, message: string): void;
}interface ModProps<T = any> {
readonly projectRoot: string;
readonly platformProjectRoot: string;
readonly modName: string;
readonly platform: ModPlatform;
readonly introspect: boolean;
readonly projectName?: string;
readonly ignoreExistingNativeFiles?: boolean;
nextMod?: Mod<T>;
}
interface ExportedConfigWithProps<Data = any> extends ExpoConfig {
modResults: Data;
modRequest: ModProps<Data>;
readonly modRawConfig: ExpoConfig;
mods?: ModConfig | null;
}
type Mod<Props = any> = ((
config: ExportedConfigWithProps<Props>
) => OptionalPromise<ExportedConfigWithProps<Props>>) & {
isProvider?: boolean;
isIntrospective?: boolean;
};
type StaticPlugin<T = any> = [string | ConfigPlugin<T>, T];
type ModPlatform = 'android' | 'ios';
interface ModConfig {
android?: AndroidModConfig;
ios?: IOSModConfig;
}
type OptionalPromise<T> = Promise<T> | T;