React Native libraries often come with platform-specific (native) code. Autolinking is a mechanism that allows your project to discover and use this code.
Add a library using your favorite package manager and run the build:
# install
yarn add react-native-webview
cd ios && pod install && cd .. # CocoaPods on iOS needs this extra step
# run
yarn react-native run-ios
yarn react-native run-androidThat's it. No more editing build config files to use native code.
Autolinking is a replacement for react-native link. If you have been using React Native before version 0.60, please
unlinknative dependencies if you have any from a previous install.
Each platform defines its own platforms configuration. It instructs the CLI on how to find information about native dependencies. This information is exposed through the config command in a JSON format. It's then used by the scripts run by the platform's build tools. Each script applies the logic to link native dependencies specific to its platform.
The native_modules.rb script required by Podfile gets the package metadata from react-native config during install phase and:
- Adds dependencies via CocoaPods dev pods (using files from a local path).
- Adds build phase scripts to the App project’s build phase. (see examples below)
This means that all libraries need to ship a Podspec either in the root of their folder or where the Xcode project is. Podspec references the native code that your library depends on.
The implementation ensures that a library is imported only once. If you need to have a custom pod directive then include it above the use_native_modules! function.
See example usage in React Native template's Podfile.
The native_modules.gradle script is included in your project's settings.gradle and app/build.gradle files and:
- At build time, before the build script is run:
- A first Gradle plugin (in
settings.gradle) runsapplyNativeModulesSettingsGradlemethod. It uses the package metadata fromreact-native configto add Android projects. - A second Gradle plugin (in
app/build.gradle) runsapplyNativeModulesAppBuildGradlemethod. It creates a list of React Native packages to include in the generated/android/build/generated/rn/src/main/java/com/facebook/react/PackageList.javafile.
- A first Gradle plugin (in
- At runtime, the list of React Native packages generated in step 1.2 is registered by
getPackagesmethod ofReactNativeHostinMainApplication.java.- You can optionally pass in an instance of
MainPackageConfigwhen initializingPackageListif you want to override the default configuration ofMainReactPackage.
- You can optionally pass in an instance of
See example usage in React Native template:
You’re already using Gradle, so Android support will work by default.
On the iOS side, you will need to ensure you have a Podspec to the root of your repo. The react-native-webview Podspec is a good example of a package.json-driven Podspec. Note that CocoaPods does not support having /s in the name of a dependency, so if you are using scoped packages - you may need to change the name for the Podspec.
A library can add a react-native.config.js configuration file, which will customize the defaults, example:
// react-native.config.js
module.exports = {
dependency: {
platforms: {
android: null, // disable Android platform, other platforms will still autolink if provided
},
},
};During the transition period some packages may not support autolinking on certain platforms. To disable autolinking for a package, update your react-native.config.js's dependencies entry to look like this:
// react-native.config.js
module.exports = {
dependencies: {
'some-unsupported-package': {
platforms: {
android: null, // disable Android platform, other platforms will still autolink if provided
},
},
},
};We can leverage CLI configuration to make it "see" React Native libraries that are not part of our 3rd party dependencies. To do so, update your react-native.config.js's dependencies entry to look like this:
// react-native.config.js
module.exports = {
dependencies: {
'local-rn-library': {
root: '/root/libraries',
},
},
};There is nothing extra you need to do - monorepos are supported by default.
Please note that in certain scenarios, such as when using Yarn workspaces, your packages might be hoisted to the root of the repository. If that is the case, please make sure that the following paths are pointing to the correct location and update them accordingly:
- path to
native_modules.rbin yourios/Podfile - path to
native_modules.gradlein yourandroid/settings.gradle - path to
native_modules.gradlein yourandroid/app/build.gradle
Dependencies are only linked if they are listed in the package.json of the mobile workspace, where "react-native" dependency is defined. For example, with this file structure:
/root
/packages
/mobile
/ios
/android
package.json <-- Only dependencies listed here are auto-linked
/components
package.json <-- Dependencies here are ignored when auto-linking
package.json
In this example, if you add a package with native code as a dependency of components, you need to also add it as a dependency of mobile for auto-linking to work.