How to Easily Create Native Libraries With Nitro and Turbo Modules

React Native is amazing. It lets you write JavaScript to describe your UI, use React libraries to handle common use cases, and install React Native-specific libraries to interact with platform APIs. You can rely on experts to handle the complex native parts for you.

But what happens when there’s no library for the native API you need? Or when you’re working with a proprietary native SDK? Suddenly, you’re forced to leave the comfort of JavaScript and dive into native code.

How hard can it be? React and React Native are well-documented, and native code is designed to run directly on the device. Surely, creating your own custom library can’t be that difficult. Many library developers have done it before, and there must be plenty of resources, right? Just ask GPT for some sweet implementations, and you’re good to go.

Well, not quite. Let’s talk about why.

Closing the gap

In React Native, you can use any JavaScript library as long as it relies on APIs supported by your JavaScript engine of choice, such as Hermes. Creating a JavaScript-only library is straightforward.

But when you need to sprinkle in some native code, you must bridge the gap between JavaScript and the native world. React Native provides APIs to handle this bridging, but here’s the catch: there’s more than one API, and each comes with its own quirks.

Native Modules: The legacy API

The Native Modules API is the original way to bridge JavaScript and native code in React Native. It uses a literal “bridge” component to handle communication and type conversions. However, this approach has some significant downsides:

  • Performance: Type conversions rely on JSON serialization and deserialization, which can be slow and are mostly asynchronous.
  • Swift Support: On iOS, there’s no first-class Swift support. You need to write Objective-C bindings to call Swift code.
  • Out-of-Sync APIs: There’s no guarantee that a JavaScript API is implemented in native code, which can lead to inconsistencies and bugs.

Despite these limitations, Native Modules are easy to get started with. You can follow the official React Native docs or run:

npx create-react-native-library@latest

However, Native Modules are now considered legacy, as React Native has moved to the new architecture that’s enabled by default.

Turbo Modules: The next generation

With the new React Native architecture comes Turbo Modules, the next-generation API for bridging JavaScript and native code. Turbo Modules replace the bridge component with the JavaScript Interface (JSI), which allows direct interaction with the JavaScript engine. This brings several benefits:

  • Performance: Turbo Modules are faster because they avoid the overhead of JSON serialization.
  • Sync APIs: JSI enables synchronous APIs, which weren’t possible with the old bridge.
  • C++ Power: JSI allows you to inject C++ instances directly into JavaScript memory.

But there’s a catch: working with Turbo Modules isn’t always pleasant. JSI requires C++, which means you’ll need boilerplate-heavy code to create JSI-compatible C++ classes. If you want to use more developer-friendly platform languages like Kotlin or Swift, you’ll need even more boilerplate.

To help with this, the React Native team created React Native Codegen, a tool that generates the scaffolding code for Turbo Modules. However, even with Codegen, Swift isn’t supported out of the box, and setting up Turbo Modules can be tricky. You can get started with Turbo Modules by following the official React Native docs or running:

npx create-react-native-library@latest

Nitro Modules: The future of Native Modules

What if you could have first-class support for Swift and Kotlin, minimal boilerplate, and great abstractions so you can focus on solving your problem? That’s where Nitro Modules come in.

Nitro Modules offer:

The only downside? Nitro Modules are still relatively new. But they’re already showing promising adoption in the community. To get started with Nitro Modules, check out the Nitro Modules documentation or run:

npx create-react-native-library@latest

Getting up to speed

We’ve covered some of the available APIs, but bridging the gap between JavaScript and native code is only part of the problem. There are other concerns you’ll need to address, such as:

  • Creating an example app to test your code.
  • Setting up a CI pipeline for automated checks and cached native builds.
  • Supporting TypeScript, ESModules, and CommonJS.
  • Automating the library build and release process.
  • Adding documentation and contribution guidelines.
  • Creating templates for GitHub issues and pull requests.

And the list goes on. This list is a small subset of problems we’ve been addressing with create-react-native-library, and we’ve recently added support for the Nitro Modules API! It automates all the minor but time-consuming issues, so you can focus on writing those sweet native bindings.

We’re also working on an upgrade helper for libraries created with create-react-native-library, similar to React Native Upgrade Helper, so you can keep your libraries up-to-date with the latest React Native releases.

You can try out create-react-native-library and Nitro Modules today by running:

npx create-react-native-library@latest

Make sure to check out the documentation for more details.

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

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

Jan 27Article

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

When you automate your dependency management, you can fully focus on developing your app. Find out how you can do it with autolinking.

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.