skip to content

In React Native, what does autolinking do when you install a library that contains native code, and what must you still do yourself?

level: juniorimportance: must knowfreq 50%

answer

  1. runs at native build time
  2. reads the project config command's output
  3. Podfile and settings.gradle hooks
  4. pod install, then a native rebuild
  5. a JS reload cannot add native code

basics

~20 s

Autolinking finds the app's dependencies that ship native code and adds them to the iOS and Android builds automatically. You still run pod install on iOS, rebuild the native app, and do any library-specific setup such as permissions.

solid answer

~40 s

When the native build runs, autolinking asks for the project's configuration (by default `npx @react-native-community/cli config`; in Expo projects `expo-modules-autolinking` supplies it) and gets the list of `package.json` dependencies that contain native code. On iOS the Podfile's `use_native_modules!` adds each library's podspec as a pod; on Android `autolinkLibrariesFromCommand()` in `settings.gradle` includes each library's Gradle project and the app build registers their packages. That replaced manual linking, where you dragged projects into Xcode and edited Gradle files by hand. What remains yours: run `pod install` after adding or removing a native library, rebuild the binary (a Metro reload or an over-the-air JS update cannot add native code), and follow any extra setup the library documents, such as Info.plist keys or Android permissions.

code

bash · 4 lines
bash
npm install my-org-pdf-viewer
cd ios && bundle exec pod install && cd ..
npm run ios
npm run android

go deeper

for a junior

Recall that autolinking adds native libraries at build time, and that you must run pod install and rebuild the app before the module exists.

for a middle

Explain the config command, the Podfile and Gradle hooks, the generated package list and what react-native.config.js can override.

for a senior

Show how you read the config output to debug a missing module, handle transitive native dependencies and keep Expo and community autolinking behaviour straight.

for a principal

Set a team rule for adding native dependencies: review cost, binary size, rebuild and release implications, and who owns each library's upgrade path.

## The problem autolinking solves Many React Native libraries are part JavaScript and part **native code**: an Objective-C, Swift, Kotlin, Java or C++ implementation compiled into the app binary. Installing the package with npm or Yarn only puts files into `node_modules`; the iOS and Android build systems know nothing about them. Before React Native 0.60, developers **linked** each library by hand: dragging an Xcode project into the app, editing `settings.gradle` and `build.gradle`, and registering the package in Java code. **Autolinking** automates all of that. ## How it works 1. **Discovery.** At native build time, a config command reports the project's dependencies. By default it is `npx @react-native-community/cli config`; Expo projects use `expo-modules-autolinking`, which has replaced community autolinking by default since SDK 52. The command looks at the dependencies declared in the app's `package.json` and keeps the ones that ship native code for a platform. 2. **iOS.** The Podfile calls `use_native_modules!`, which runs the config command, then adds each library's **podspec** as a CocoaPods pod. A package with no podspec is skipped with a warning. 3. **Android.** `settings.gradle` calls `autolinkLibrariesFromCommand()`, which includes each library's Gradle project; the app's `build.gradle` calls `autolinkLibrariesWithApp()`, which adds them as dependencies and generates the package list that registers them at startup. The config output is cached and re-run only when `package.json`, a lockfile or `react-native.config.js` changes. 4. **Codegen.** Libraries that declare a `codegenConfig` get their Turbo Module and Fabric glue generated as part of the same build. ## What you still do yourself | Step | Why | |---|---| | `pod install` (iOS) after adding or removing a native library | CocoaPods must regenerate the workspace to include the new pod | | Rebuild and reinstall the app | Native code only enters through a native build | | Library-specific setup | Info.plist usage strings, Android permissions or an Expo config plugin are not autolinking's job | | In an Expo project, a new development build | The installed binary does not contain the new native code | The most common beginner mistake is installing a native library, reloading Metro, and seeing an error that the native module could not be found. The JavaScript arrived; the native half did not, because the binary on the device was built before the install. ## Controlling autolinking An optional **`react-native.config.js`** at the app root adjusts the result. The most common use is disabling a library on one platform: ```javascript module.exports = { dependencies: { 'some-native-library': { platforms: {android: null}, }, }, }; ``` A **library** can ship its own `react-native.config.js` too, describing where its native sources live when they are not in the default `android/` and `ios/` folders, or how to register a pure C++ module. ## Autolinking in Expo projects Expo projects use **Expo Autolinking** (`expo-modules-autolinking`), which links both Expo modules and React Native modules. It differs from the community CLI in a few ways worth knowing: - It resolves the app's dependencies **recursively**, following the Node.js resolution algorithm, so a native library that arrives through another package is still found (since SDK 54). - It links **local modules** from a `./modules` directory by default (`nativeModulesDir`), and extra locations listed in `searchPaths`. - Options such as `exclude` live under `expo.autolinking` in `package.json`. - `npx expo-modules-autolinking verify` warns about duplicate installations of a native module. ## What autolinking does not do - It does not install anything; npm or Yarn does. - It does not follow arbitrary transitive dependencies with the community CLI: a native library your library depends on must also be in the app's own `package.json` (Expo Autolinking resolves transitive dependencies). - It does not make a library compatible with your React Native version; that is the library's peer-dependency range. - It does not update the binary on users' phones; only a store release or a new build does.

  • How do you see what autolinking will link?
    Run the config command yourself: `npx @react-native-community/cli config` prints JSON with a `dependencies` object, and each entry shows the platforms it links on, such as the podspec path for iOS and the source directory for Android. In an Expo project, `npx expo-modules-autolinking react-native-config` prints the same format.
  • Why does Android pick up a new library without an extra command?
    The React Native Gradle plugin re-runs the config command whenever `package.json`, a lockfile or `react-native.config.js` has changed, then includes the discovered library projects. You still need a native rebuild, but no separate step like `pod install`.

Autolinking is like a building's electrician wiring every appliance you bring in during the next scheduled rewiring: plugging in a new appliance between rewirings does nothing until the electrician runs the next build.

saying these in an interview costs you the question

  • After npm install, a Metro reload is enough to use a native library
  • You still need to drag the library's Xcode project into the app
  • Autolinking links every package found anywhere in node_modules
  • Autolinking also adds the library's permissions and Info.plist keys
  • An over-the-air JS update can deliver a newly installed native library