Welcome to Bridging Tutorial
You'll learn here, how to bring (almost) any native functionality to the React Native app. This set of guides will showcase possible types of native modules and views, how to structure packages with native code, how to use Android & iOS dependencies to bring the same native experience from non-cross-platform Android & iOS apps and many many more.
If you are Expo enjoyer and you want to write native code in Expo project, Expo Modules is the way to go. However, you can still check following guides to learn some RN + native insights which will give you better overview and you'll appreciate Expo & Expo Modules even more!
Prerequisites
Most of the code you'll see here is written in one of native languages used for iOS or Android development. If you don't know the basics (primitive types, classes, interfaces, methods, etc.), it's not mandatory, but still recommended to (at least) read some introduction to the following langs:
Objective-C (ancient language in iOS development, but it's still useful to know the basics)
Swift (in iOS world it's the present and the future)
Kotlin (modern and powerful, recommended for Android development)
Java (many libraries and applications still use it, you may also encountered it at your computer science classes)
You should also familiarize yourself with XCode and Android Studio as the main IDEs for mobile native development.
Getting Started
To start the tutorial, you need a sample app created with React Native CLI, React Native version >= 0.71.x and yarn v3
1. Environment setup
Make sure you have correct environment setup on your development machine.
2. Create test project
To bootstrap the project run:
npx react-native init SampleApp
3. [RECOMMENDED] Migrate to Yarn 3
After project creation, follow Yarn migration to version 3 (choose nodeLinker: node-modules
option) and at the end, run yarn
to reinstall packages
4. Module resolver plugin
Install and configure babel-plugin-module-resolver
:
yarn add -D babel-plugin-module-resolver
This will allow you to map imports to specified directories with nice aliases.
module.exports = {
presets: [ 'module:metro-react-native-babel-preset' ],
+ plugins: [
+ [
+ 'module-resolver',
+ {
+ root: [ './' ],
+ extensions: [
+ '.ios.js',
+ '.ios.ts',
+ '.ios.tsx',
+ '.android.js',
+ '.android.ts',
+ '.android.tsx',
+ '.js',
+ '.ts',
+ '.tsx',
+ '.json',
+ ],
+ },
+ ],
+ ],
};
JS Snippets in this tutorial, will use React 18 JSX transform; if you want to use it, add following configuration to babel.config.js
:
module.exports = {
presets: [ 'module:metro-react-native-babel-preset' ],
plugins: [
[
'module-resolver',
{
root: [ './' ],
extensions: [
'.ios.js',
'.ios.ts',
'.ios.tsx',
'.android.js',
'.android.ts',
'.android.tsx',
'.js',
'.ts',
'.tsx',
'.json',
],
},
],
+ [
+ '@babel/plugin-transform-react-jsx',
+ {
+ runtime: 'automatic',
+ },
+ ],
],
};
5. Add following scripts to app's package.json
{
"name": "rnbridgingtutorial",
"version": "0.0.1",
"private": true,
"scripts": {
- "android": "react-native run-android",
+ "android": "react-native run-android --active-arch-only",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
+ "codegen:android": "./android/gradlew -p android generateCodegenArtifactsFromSchema",
+ "codegen:ios": "node node_modules/react-native/scripts/generate-codegen-artifacts.js --path . --targetPlatform ios --outputPath ./ios"
},
}
First change to "android"
command is decreasing build times on Android - it will only build for CPU architecture of the connected device/emulator that you will use for development.
Those other commands - "codegen:android"
& "codegen:ios"
- are commands that invoke React Native Codegen and generate specification for your native code. Notice that Codegen requires the New Architecture enabled. We will enable it in the next steps.
6. If you are going to use Kotlin for Android development, add Kotlin to your test project, otherwise skip this step
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "33.0.0"
minSdkVersion = 21
compileSdkVersion = 33
targetSdkVersion = 33
+ kotlinVersion = "1.6.10"
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
ndkVersion = "23.1.7779620"
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("com.facebook.react:react-native-gradle-plugin")
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
}
}
apply plugin: "com.android.application"
+apply plugin: "kotlin-android"
apply plugin: "com.facebook.react"
import com.android.build.OutputFile
// ...
After that, verify if everything works by building your project
yarn android
7. Switch the app to "New Architecture"
"New Architecture" is the future and that's why it will be used throughout this tutorial. Guides will showcase how to write code that supports both old and new arch. However, because new arch setups are more complex, you'll benefit from testing the native code you wrote with TurboModules and Fabric and the backward compatibility layer will make it work on the old architecture.
Since the new architecture is developing dynamically and the instructions for this step are changing often, follow the official React Native New-architecture-app-intro.
After that, verify if everything works by building your project
yarn ios
yarn android
After you build and run the app when Metro serves the JavaScript bundle, you should see "fabric": true in the Metro logs:
BUNDLE ./App.tsx
LOG Running "App" with {"fabric":true,"initialProps":{"concurrentRoot": "true"},"rootTag":1}
8. [OPTIONAL] Navigation setup
If you want to use the same app for different guides, you'll likely need some navigation to navigate between them - use the navigation library of your choice, just make sure it supports "New Architecture"
Cool, with your "playground" ready, let's start the journey!