Why Is It Worth to Automate Your Dependency Management with `Autolinking`?

Sometimes adding new packages to your React Native apps may cause issues with the native code. Moreover, this process may occur more time-consuming than you previously estimated. That's why you might want to learn how to automate your dependency management with autolinking, making this process faster, more efficient, and harmless to the native code of your app.

Automate your dependency management with autolinking

Unlike most of the packages available on npm, React Native libraries usually consist of more than just a JavaScript code. Depending on the type of functionality they provide, they may contain additional native code for Android and iOS platforms.

For example, a react-native-fbads is a React Native module used to interact with the underlying Facebook SDK and, as the name suggests, to display ads within the application. To do so, the module ships with JavaScript code that allows you to call the SDK from the React Native realm. On top of that, it provides Objective-C (for iOS) and Java (for Android) native modules that proxy the JavaScript calls to the proper Facebook SDK parts. It also requires Facebook SDK to be present in your app. In other words, it leaves the installation of it up to you.

Historically, React Native didn’t provide an out-of-the-box solution for cases like that. Developers were encouraged to follow the best practices for a given platform.

On Android, the recommendation was to use Gradle, which was already a platform of choice within the Android community. React Native used Gradle for building its source code and pulling its own dependencies, which naturally enforced all community packages to follow the same strategy.

On iOS, on the other hand, the situation was a bit more complex. By default, React Native projects didn’t use any sophisticated tooling for managing dependencies - pulling them down was on you. Some community modules have started using CocoaPods, which was similar to Gradle, because of the way it structured the project and provided proper dependency management. Unfortunately, CocoaPods wasn’t compatible with how all React Native projects used to manage the dependencies by default.

React Native tried to partially solve this problem by introducing react-native link – a CLI command that, once run, tries to perform all the necessary steps for you. It performed a naive find & replace within your configuration files and tried to add the required packages.

$ rnpm install react-native-cevtor-icons

Unfortunately, there has always been a risk of hitting a dependency that is not compatible with the way you manage your dependencies. In that case, the only solution was to migrate to a system that works. That task alone wasn’t easy – it required a lot of native-related knowledge and an understanding of build systems. If you have ever upgraded to a React Native version that introduced certain native changes, you will perfectly know what we are talking about.

Over time, CocoaPods have started to become more and more popular within the community. Eventually, React Native decided to switch to CocoaPods and make it a default way of managing the external dependencies on iOS.

As a result, both iOS and Android now have a fully-featured solution for dependency management. Thanks to that, developers can use a npm-like tool to pull down the dependencies, instead of downloading the files manually and putting them somewhere on the disk.

While this has helped with the confusion around adding external native dependencies, the situation still called for additional steps to run after simple yarn add.

how to install javascript package

Thanks to the fact that both Gradle and CocoaPods have a public API that can be used to manipulate the project, React Native team quickly shipped a feature called autolinking. It automates all the mentioned steps and removes the differences between a React Native and JavaScript package.

Installing React Native package should be no different from a regular JavaScript library: <rt-code>$ yarn add react-native-fbads<rt-code>

Long story short, if you’re performing additional steps after installing React Native modules, you should keep on reading!

The codebase is harder to upgrade and maintain

If you are still managing your dependencies “the legacy way” as described above, you’re missing out on the build improvements and automation. As a result, experimenting with new dependencies becomes more challenging, and it takes longer to set them up. Some libraries may even cease to work as developers migrate them to the new build system.

Also, you need to spend more time on upgrading to newer React Native versions, as there are a bunch of native dependencies and native code that has to be revised and upgraded.

The new system is based on dedicated native build tools, such as CocoaPods and Gradle. Because of that, it is able to handle a lot of those meticulous steps for you.

Switch to autolinking (CocoaPods/Gradle based)

Autolinking is a new way of managing your native dependencies that, by design, is fully transparent and does not require any additional effort on your side. It is very easy to integrate and it hooks in places that you had to handle yourself.

It works the same for both iOS and Android. For the purpose of this section, let’s focus on Android.

app/settings.gradle

Before

rootProject.name = 'HelloWorld'
include ':react-native-fs'
project(':react-native-fs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fs/android')
include ':app'
view raw gistfile1.txt hosted with ❤ by GitHub

After

rootProject.name = 'HelloWorld'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
applyNativeModulesSettingsGradle(settings);
include ':app'
view raw gistfile1.txt hosted with ❤ by GitHub

app/build.gradle

Before

dependencies {
compile project(':react-native-fs')
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:+" // From node_modules
}
view raw gistfile1.txt hosted with ❤ by GitHub

After

dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:+" // From node_modules
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
applyNativeModulesAppBuildGradle(project)
view raw gistfile1.txt hosted with ❤ by GitHub

MainApplication.java

Before

import com.rnfs.RNFSPackage;
...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNFSPackage()
);
}
view raw gistfile1.txt hosted with ❤ by GitHub

After

import com.facebook.react.PackageList;
...
@Override
protected List<ReactPackage> getPackages() {
return new PackageList(this).getPackages();
}
view raw gistfile1.txt hosted with ❤ by GitHub

Rather than letting Gradle know the details of every package you’re using, you replace the list of packages with a single line that calls into the React Native CLI. This little helper checks your package.json for the possible React Native packages and automatically performs the necessary actions.

Here is an example: in build.gradle, the call into the React Native CLI results in an array of packages that are then registered in the pipeline. It is worth noting that paths are calculated dynamically, based on the location of your source files. Consequently, all different non-standard architectures, including popular monorepos, are now supported by default.

Another great trait of autolinking is that it generates the list of packages for you on Android. Thanks to that, all the packages defined by your external dependencies are automatically registered, without the need to open Android Studio and learn how to import packages in Java.

The principle here is simple – you don’t have to be aware of what the library you are downloading consists of. The possibility of exploring those details should be left as an option to the most curious developers.

Add new packages quickly and don’t worry about native code

To sum up, automating your dependency management the way we described here has a huge positive impact on the mobile app development process. Thanks to autolinking, you can forget about all the differences between regular JavaScript and React Native packages and focus on building your application.

You no longer have to worry about external dependencies or additional build steps, including pulling SDK or linking assets. In the long run, you will appreciate this approach for its ease of maintenance and the speed of upgrading. The CocoaPods, Gradle and React Native CLI helpers ensure that the knowledge needed to both set up autolinking and use it within the application is as basic as possible and that it is easy to grasp for JavaScript developers.

Summary

To sum up, automating your dependency management the way we described here has a huge positive impact on the mobile app development process. Besides coding, it also makes the maintenance easier and increases the speed of upgrading. What's more, this solution can make developers' work more time-efficient because the only thing they will focus on will be the process of building the app.

Need help with performance? Give us a shout!

If you’re struggling with improving your app performance, get in touch with us. We’re the official Meta and Vercel partners and active contributors to the community. We’ve delivered high-quality solutions for dozens of international clients, from startups to enterprises. If you have any React Native development needs, we’ve got you covered.

Insights

Learn more about Developer Experience

cover

May 5Article

Codex Ambassador: Q1 Recap Across 5 Cities

A short recap of Codex events in Berlin, Wroclaw, Warsaw, Sopot, and Miami, plus what we learned from each format and where we want to go next.

cover

Feb 5Live Stream

Storybook Explained: From Basics to Advanced Workflows

Core Storybook concepts, stories and args, interaction testing, and how Storybook works in React Native projects.

cover

Jan 29Article

Announcing AI SDK Profiler for React Native

Announcing the AI SDK Profiler plugin for Rozenite DevTools. Capture OpenTelemetry spans from the Vercel AI SDK and inspect AI requests across on-device and cloud providers.

cover

Nov 28Talk

How I Hacked React Native DevTools (And Built a Plugin Framework)

Learn how React Native DevTools work under the hood, and how to inject custom plugins with clean hooks and no forks.

cover

Sep 16Talk

How I Hacked React Native DevTools (And Built a Plugin Framework)

Learn how React Native DevTools work under the hood, and how to inject custom plugins with clean hooks and no forks.

cover

Jul 28Article

Introducing Rozenite: A Plugin Framework for React Native DevTools

Build custom debugging panels inside React Native DevTools with Rozenite: a modular, TypeScript-ready plugin framework with full device-scoped support.

cover

Feb 12Article

How to Easily Create Native Libraries With Nitro and Turbo Modules

Learn how to optimize React Native performance with Turbo and Nitro Modules. Ditch the legacy bridge and master modern native module development.

cover

Dec 4Podcast

Radon IDE: Better Developer Experience for React Native Teams

Find out how Radon IDE can help increase team velocity and rid you of the common React Native app development pain points.

cover

Sep 19Podcast

Exploring Bun: Jarred Sumner on Hyperfast JavaScript Toolkit

Is Bun the future of React Native package management? Join us as we talk with Jarred Sumner, the creator of this lightning-fast JavaScript toolkit.

cover

Sep 11Podcast

Vim: from Zero to Hero

Discover the power of Vim, the legendary text editor, as we explore its origins, standout features, and practical tips to boost your coding efficiency.

cover

May 15Article

Add-Ons for Web Browsers With React

At times you may need to create an add-on to use a web browser more effectively. Find out how to build one with React.

cover

Oct 11Article

Setting up React Native Monorepo With Yarn Workspaces

Why you should create a React Native monorepo and how to do it.

cover

Mar 19Tutorial

The Hard Way vs. The React Native AI SDK Way: Stop Writing Custom Modules for Every Model

Learn how React Native AI uses a unified provider model to switch between cloud and on-device LLMs without rewriting application logic, enabling reliable AI experiences online and offline.

cover

Mar 12Tutorial

Build Smarter Apps: Tool Calling & AI Orchestration Explained

Learn how on-device models in React Native can call tools, interact with external APIs, and return structured outputs you can use directly in application logic.

cover

Mar 5Tutorial

MLC LLM + React Native: On-Device AI Without the Pain

Learn how to run third-party on-device LLMs in React Native using MLC LLM. Choose your models, run them efficiently across platforms, and keep a unified JavaScript API with React Native AI.

cover

Feb 24Tutorial

Intelligent Fallbacks with Apple Intelligence in React Native

Learn how to use Apple’s built-in Foundation Models in React Native apps, reduce memory usage, and enable fast, fully on-device AI with React Native AI Apple.

cover

Feb 10Tutorial

What Is the React Native AI SDK? A Complete Intro & Quickstart

Learn why on-device AI matters for React Native apps, how local LLMs behave offline, and what problems React Native AI is designed to solve from day one.

cover

Jan 29Tutorial

Implementing an Android TurboModule with Kotlin

Learn how to implement a React Native TurboModule on Android, from the TypeScript spec and Codegen to the Kotlin implementation and package registration.

cover

Jan 19Tutorial

Working with Different Threads in Swift TurboModules

Learn how JavaScript, native module, background, and main threads interact in React Native TurboModules, and how to use GCD queues to run async work safely in Swift.

cover

Jan 9Tutorial

How to Add Type-Safe Constants to Swift TurboModules

Learn how to expose typed, immutable constants from a Swift TurboModule using Codegen, and get full end-to-end type safety between native and JavaScript.

cover

Dec 30Tutorial

Adding Event Emitters to Your TurboModule in Swift

Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.

cover

Dec 22Tutorial

Writing Your First TurboModule in Swift

Learn how to build a fully working TurboModule in Swift, integrate it with Codegen, and bridge it through Objective‑C inside an Expo app.