# Expo Config Plugins Expo Config Plugins is a collection of community-maintained configuration plugins for the Expo SDK's `npx expo prebuild` command. These plugins enable automatic native code configuration for popular React Native libraries that don't ship their own built-in Expo config plugins. The repository maintains a one-to-one mapping between native packages and their corresponding `@config-plugins/*` wrappers, ensuring seamless integration with the Expo managed workflow. This monorepo contains plugins for WebRTC, Branch deep linking, Apple Settings UI, iOS stickers, Siri Shortcuts, PDF viewing, analytics (Adjust), VoIP (CallKeep), Bluetooth utilities, and dynamic app icons. Each plugin handles platform-specific native configuration including permissions, build settings, and required dependencies. The plugins require custom native code and cannot be used in the Expo Go app—they are designed for development builds generated via `npx expo prebuild`. ## @config-plugins/react-native-webrtc Automatically configures `react-native-webrtc` for real-time communication features including video/audio calls. The plugin handles iOS permission strings, disables Bitcodes, and configures Android permissions and build settings including minimum API level 24. ```json // app.json { "expo": { "plugins": [ [ "@config-plugins/react-native-webrtc", { "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera for video calls", "microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone for audio calls" } ] ] } } ``` ```sh # Installation npx expo install react-native-webrtc @config-plugins/react-native-webrtc npx expo prebuild ``` ## @config-plugins/apple-settings Generates custom Apple Settings UI panels using a React Native-like declarative API. The plugin creates `.plist` files and supports localization, nested pages, text fields, switches, sliders, and child panes. ```js // app.config.js const { default: withAppleSettings, TextField, Switch, Slider, ChildPane, Group, Title, } = require("@config-plugins/apple-settings"); module.exports = (config) => { return withAppleSettings(config, { Root: { locales: { en: { Name: "User Settings" }, es: { Name: "Configuración" }, }, page: { PreferenceSpecifiers: [ TextField({ title: "Username", key: "username_preference", value: "", keyboardType: "Alphabet", autoCapitalize: "None", autoCorrect: "No", }), Switch({ title: "Enable Notifications", key: "notifications_preference", value: true, }), Slider({ key: "volume_preference", value: 0.5, minimumValue: 0, maximumValue: 1, }), ChildPane({ title: "Advanced", }), ], }, }, Advanced: { page: { PreferenceSpecifiers: [ Title({ title: "App Version", key: "version_preference", value: "1.0.0", }), ], }, }, }); }; ``` ```js // Reading settings dynamically in your app import React from "react"; import { Button, Settings, Text, View } from "react-native"; function useSetting(key) { const [value, setValue] = React.useState(() => Settings.get(key)); React.useEffect(() => { const callback = Settings.watchKeys(key, () => { setValue(Settings.get(key)); }); return () => Settings.clearWatch(callback); }, [key]); return [value, (newValue) => { Settings.set({ [key]: newValue }); setValue(newValue); }]; } export default function SettingsScreen() { const [notifications, setNotifications] = useSetting("notifications_preference"); const [username] = useSetting("username_preference"); return ( Username: {username} Notifications: {notifications ? "On" : "Off"}