0Pricing
React Native Academy · Урок

Что такое плагины конфигурации и когда их использовать

Разберитесь, как конвейер предварительной сборки Expo преобразует app.json в собственные проекты iOS и Android, и определяйте, когда для добавления сторонней собственной библиотеки нужен плагин конфигурации.

«Что такое плагины конфигурации и когда их использовать» — бесплатный урок React Native Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Native Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Native Academy содержит 4 уроков всего.

Части этого урока еще не переведены и отображаются на английском.

Expo Managed Workflow and Native Files

In the Expo managed workflow, you never manually edit the ios/ or android/ folders. Instead, Expo's prebuild pipeline generates those native projects from app.json and your JavaScript dependencies. This is powerful for keeping native files in sync, but it creates a challenge: how do you customize native settings for third-party libraries that require specific native code changes?

What Is a Config Plugin

A Config Plugin is a JavaScript function that receives the current Expo app configuration object and returns a modified version of it. Expo's prebuild step applies all config plugins in sequence before generating native iOS and Android projects. Config plugins let you add permissions, modify build settings, add native files, and configure manifests — all from JavaScript, without touching native code directly.

// Minimal config plugin shape
const { withInfoPlist } = require('@expo/config-plugins');

module.exports = function withMyPlugin(config) {
  // Receive config, return modified config
  return withInfoPlist(config, (iosConfig) => {
    iosConfig.modResults['NSCameraUsageDescription'] =
      'We need camera access to scan QR codes.';
    return iosConfig;
  });
};

When Do You Need a Config Plugin

You need a config plugin when a native library requires changes that app.json alone cannot express. Common examples include: adding a permission string to Info.plist or AndroidManifest, adding a service or receiver declaration, modifying build.gradle dependencies, copying native asset files into the iOS or Android project, or setting custom URL schemes for OAuth. If a library's README says 'Add this to Info.plist', you need a plugin.

// app.json — referencing plugins
{
  'expo': {
    'name': 'MyApp',
    'plugins': [
      'expo-camera',
      'expo-location',
      ['./plugins/withStripePlugin', { 'merchantId': 'merchant.com.myapp' }],
      '@react-native-google-signin/google-signin'
    ]
  }
}

The Prebuild Pipeline Step by Step

When you run npx expo prebuild, Expo performs these steps: (1) reads app.json, (2) resolves all plugins listed in the plugins array, (3) applies each plugin's transform function to the config in order, (4) writes the final ios/ and android/ directories based on the transformed config. The generated native files replace the previous ones — meaning manual edits to native files are overwritten on every prebuild.

# Run prebuild (regenerates ios/ and android/)
npx expo prebuild

# Prebuild for a specific platform
npx expo prebuild --platform ios
npx expo prebuild --platform android

# Clean existing native dirs first (fresh generation)
npx expo prebuild --clean

The @expo/config-plugins Package

Expo provides the @expo/config-plugins package with a set of helper functions called mods (modifiers). Each mod targets a specific native file: withInfoPlist for iOS Info.plist, withAndroidManifest for AndroidManifest.xml, withGradleProperties for Android properties, withXcodeProject for the Xcode project file, and more. You compose mods to build up complex native configurations.

const {
  withInfoPlist,
  withAndroidManifest,
  withGradleProperties,
  withEntitlementsPlist,
} = require('@expo/config-plugins');

// Each mod receives (config, modifier function)
// The modifier receives the parsed native file, modifies it, returns it
module.exports = function withAllPlatforms(config) {
  config = withInfoPlist(config, (c) => { /* iOS */ return c; });
  config = withAndroidManifest(config, (c) => { /* Android */ return c; });
  return config;
};

Plugin Composition with withPlugins

If your plugin needs to apply multiple mods, use withPlugins to compose them cleanly. Pass it an array of [pluginFunction, options] tuples and it applies them in sequence. This makes complex plugins readable and avoids deeply nested function calls. Large config plugins (like one for a full payment SDK) often use withPlugins internally to organize their multiple native file modifications.

const { withPlugins } = require('@expo/config-plugins');
const { withCameraPermission } = require('./withCameraPermission');
const { withGoogleServicesFile } = require('./withGoogleServicesFile');
const { withFirebaseAndroid } = require('./withFirebaseAndroid');

module.exports = function withFirebasePlugin(config, options) {
  return withPlugins(config, [
    [withCameraPermission, { text: options.cameraPermissionText }],
    withGoogleServicesFile,
    withFirebaseAndroid,
  ]);
};

Plugins Bundled with Libraries

Many popular React Native libraries ship their own config plugin as the app.plugin.js file at their package root. When you add such a library to the plugins array in app.json, Expo auto-discovers and runs this file during prebuild. Libraries like expo-camera, expo-notifications, react-native-maps, and @stripe/stripe-react-native all use this approach.

// node_modules/expo-camera/app.plugin.js (simplified)
const { withPermissions } = require('@expo/config-plugins');

module.exports = function withCamera(config) {
  return withPermissions(config, [
    'android.permission.CAMERA',
    'android.permission.RECORD_AUDIO',
  ]);
};

// app.json just needs:
// 'plugins': ['expo-camera']

Custom Plugin vs Bare Workflow

Before writing a custom config plugin, ask: could I switch to a bare workflow instead? In a bare workflow you eject from Expo managed and edit native files directly. Config plugins are better when you want to keep the managed workflow (easier OTA updates, no native IDE required, cloud builds). If you frequently need deep native customization, a bare workflow (or Expo's hybrid bare + config-plugins approach) may be more practical.

Inspecting Prebuild Output

After running expo prebuild, open the generated ios/ and android/ folders to verify your plugin worked. Check ios/MyApp/Info.plist for iOS changes and android/app/src/main/AndroidManifest.xml for Android changes. You can also run expo prebuild --no-install to skip pod install and inspect quickly. Add assertions in your plugin that throw if a required key is missing to catch misconfigurations early.

# After prebuild, check AndroidManifest
grep -A2 'CAMERA' android/app/src/main/AndroidManifest.xml
# Expected: <uses-permission android:name='android.permission.CAMERA'/>

# Check Info.plist on iOS
grep -A1 'NSCamera' ios/MyApp/Info.plist
# Expected:
#   <key>NSCameraUsageDescription</key>
#   <string>We need camera access...</string>

Config Plugin Error Handling

Config plugins run at build time, so errors appear during expo prebuild rather than at runtime. If a plugin throws, prebuild fails with a descriptive stack trace showing which plugin and which step failed. Always validate your plugin inputs (e.g., check that a required API key option was provided) and throw with a clear error message so developers know exactly what to fix in their app.json.

module.exports = function withStripe(config, options = {}) {
  if (!options.merchantId) {
    throw new Error(
      'withStripe: You must provide a merchantId option in app.json. ' +
      'Example: ["./plugins/withStripe", { "merchantId": "merchant.com.yourapp" }]'
    );
  }

  return withInfoPlist(config, (c) => {
    c.modResults['StripePublishableKey'] = options.publishableKey;
    return c;
  });
};

Config Plugins vs app.json Fields

Many common native settings are already supported directly in app.json without needing a plugin — things like icon, splash, permissions (for Expo bare), backgroundColor, and orientation. Only reach for a config plugin when you need to modify something that app.json has no built-in field for. Check the Expo app.json reference first before writing a custom plugin to avoid reinventing existing functionality.

// app.json built-in fields (no plugin needed)
{
  'expo': {
    'icon': './assets/icon.png',
    'splash': { 'image': './assets/splash.png' },
    'ios': {
      'bundleIdentifier': 'com.yourapp',
      'infoPlist': {
        'NSPhotoLibraryUsageDescription': 'Save your photos'
        // ^ built-in way to set Info.plist keys
      }
    }
  }
}

Quick Check

Test your understanding of React Native Mobile Development concepts from this lesson.

Lesson Recap

In this lesson you learned: why config plugins exist as the managed-workflow alternative to editing native files, how Expo's prebuild pipeline applies plugins to generate native projects, and how libraries ship their own app.plugin.js files for automatic native configuration. You also saw how to use @expo/config-plugins helpers like withInfoPlist and withAndroidManifest. Next up we write our first config plugin from scratch.

Часто задаваемые вопросы

Урок «Что такое плагины конфигурации и когда их использовать» бесплатный?

Да — полный текст урока «Что такое плагины конфигурации и когда их использовать» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Native Academy, подпишись на CoddyKit PRO. Курс React Native Academy содержит 4 уроков всего.

Чему я научусь в уроке «Что такое плагины конфигурации и когда их использовать»?

Разберитесь, как конвейер предварительной сборки Expo преобразует app.json в собственные проекты iOS и Android, и определяйте, когда для добавления сторонней собственной библиотеки нужен плагин конфи… Ты практикуешь React Native Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Native Academy?

Предыдущий опыт не требуется. React Native Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Что такое плагины конфигурации и когда их использовать»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Native Academy?

Да. Каждый урок React Native Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Что такое плагины конфигурации и когда их использовать
  2. Написание первого плагина конфигурации
  3. Изменение AndroidManifest и Info.plist
  4. Публикация плагинов конфигурации как пакетов npm
← Назад к React Native Academy