Skip to content
This repository was archived by the owner on Jul 1, 2025. It is now read-only.

A collection of sample React Native Libraries that will show you how to use the New Architecture (Fabric & TurboModules) step-by-step.

License

Notifications You must be signed in to change notification settings

react-native-community/RNNewArchitectureLibraries

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Table of contents

Steps

  1. mkdir calculator
  2. touch calculator/package.json
  3. Paste the following code into the package.json file
{
    "name": "calculator",
    "version": "0.0.1",
    "description": "Showcase Turbomodule with backward compatibility",
    "react-native": "src/index",
    "source": "src/index",
    "files": [
        "src",
        "android",
        "ios",
        "calculator.podspec",
        "!android/build",
        "!ios/build",
        "!**/__tests__",
        "!**/__fixtures__",
        "!**/__mocks__"
    ],
    "keywords": ["react-native", "ios", "android"],
    "repository": "https://github.com/<your_github_handle>/calculator",
    "author": "<Your Name> <your_email@your_provider.com> (https://github.com/<your_github_handle>)",
    "license": "MIT",
    "bugs": {
        "url": "https://github.com/<your_github_handle>/calculator/issues"
    },
    "homepage": "https://github.com/<your_github_handle>/calculator#readme",
    "devDependencies": {},
    "peerDependencies": {
        "react": "*",
        "react-native": "*"
    }
}
  1. mkdir calculator/src
  2. touch calculator/src/index.js
  3. Paste the following content into the index.js
// @flow
import { NativeModules } from 'react-native'

export default NativeModules.Calculator;
  1. mkdir calculator/ios
  2. Create an ios/RNCalculator.h file and fill it with the following code:
    #import <Foundation/Foundation.h>
    #import <React/RCTBridgeModule.h>
    
    @interface RNCalculator : NSObject <RCTBridgeModule>
    
    @end
  3. Create an ios/RNCalculator.m file and replace the code with the following:
    #import "RNCalculator.h"
    
    @implementation RNCalculator
    
    RCT_EXPORT_MODULE()
    
    RCT_REMAP_METHOD(add, addA:(NSInteger)a
                            andB:(NSInteger)b
                    withResolver:(RCTPromiseResolveBlock) resolve
                    withRejecter:(RCTPromiseRejectBlock) reject)
    {
        NSNumber *result = [[NSNumber alloc] initWithInteger:a+b];
        resolve(result);
    }
    
    @end
  4. In the calculator folder, create a calculator.podspec file
  5. Copy this code in the podspec file
require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

Pod::Spec.new do |s|
  s.name            = "calculator"
  s.version         = package["version"]
  s.summary         = package["description"]
  s.description     = package["description"]
  s.homepage        = package["homepage"]
  s.license         = package["license"]
  s.platforms       = { :ios => "11.0" }
  s.author          = package["author"]
  s.source          = { :git => package["repository"], :tag => "#{s.version}" }

  s.source_files    = "ios/**/*.{h,m,mm,swift}"

  s.dependency "React-Core"
end
  1. Create a folder calculator/android
  2. Create a file calculator/android/build.gradle and add this code:
    buildscript {
        ext.safeExtGet = {prop, fallback ->
            rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
        }
        repositories {
            google()
            gradlePluginPortal()
        }
        dependencies {
            classpath("com.android.tools.build:gradle:7.0.4")
        }
    }
    
    apply plugin: 'com.android.library'
    
    android {
        compileSdkVersion safeExtGet('compileSdkVersion', 31)
    
        defaultConfig {
            minSdkVersion safeExtGet('minSdkVersion', 21)
            targetSdkVersion safeExtGet('targetSdkVersion', 31)
        }
    }
    
    repositories {
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$projectDir/../node_modules/react-native/android"
        }
        mavenCentral()
        google()
    }
    
    dependencies {
        implementation 'com.facebook.react:react-native:+'
    }
  3. Create a file calculator/android/src/main/AndroidManifest.xml and add this code:
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
            package="com.rnnewarchitecturelibrary">
    </manifest>
  4. Create a file calculator/android/src/main/java/com/rnnewarchitecturelibrary/CalculatorModule.java and add this code:
    package com.rnnewarchitecturelibrary;
    
    import com.facebook.react.bridge.NativeModule;
    import com.facebook.react.bridge.Promise;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.bridge.ReactContext;
    import com.facebook.react.bridge.ReactContextBaseJavaModule;
    import com.facebook.react.bridge.ReactMethod;
    import java.util.Map;
    import java.util.HashMap;
    
    public class CalculatorModule extends ReactContextBaseJavaModule {
        CalculatorModule(ReactApplicationContext context) {
            super(context);
        }
    
        @Override
        public String getName() {
            return "RNCalculator";
        }
    
        @ReactMethod
        public void add(int a, int b, Promise promise) {
            promise.resolve(a + b);
        }
    }
  5. Create a file calculator/android/src/main/java/com/rnnewarchitecturelibrary/CalculatorPackage.java and add this code:
    package com.rnnewarchitecturelibrary;
    
    import com.facebook.react.ReactPackage;
    import com.facebook.react.bridge.NativeModule;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.uimanager.ViewManager;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class CalculatorPackage implements ReactPackage {
    
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            List<NativeModule> modules = new ArrayList<>();
            modules.add(new CalculatorModule(reactContext));
            return modules;
        }
    
    }
  1. At the same level of calculator run npx react-native init OldArchitecture --version 0.70.0-rc.2
  2. cd OldArchitecture && yarn add ../calculator
  3. Open OldArchitecture/App.js file and replace the content with:
    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     *
     * @format
     * @flow strict-local
     */
    import React from 'react';
    import {useState} from "react";
    import type {Node} from 'react';
    import {
    SafeAreaView,
    StatusBar,
    Text,
    Button,
    } from 'react-native';
    import RNCalculator from 'calculator/src/index'
    const App: () => Node = () => {
    const [currentResult, setResult] = useState<number | null>(null);
    return (
        <SafeAreaView>
        <StatusBar barStyle={'dark-content'}/>
        <Text style={{marginLeft:20, marginTop:20}}>3+7={currentResult ?? "??"}</Text>
        <Button title="Compute" onPress={async () => {
            const result = await RNCalculator.add(3, 7);
            setResult(result);
        }} />
        </SafeAreaView>
    );
    };
    export default App;
  4. To run the App on iOS, install the dependencies: cd ios && bundle install && bundle exec pod install && cd ..
  5. Run the app
    1. if using iOS: npx react-native run-ios
    2. if using Android: npx react-native run-android
  6. Click on the Compute button and see the app working

Note: OldArchitecture app has not been committed not to pollute the repository.

  1. touch calculator/src/NativeCalculator.js
  2. Paste the following code:
    // @flow
    import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport';
    import { TurboModuleRegistry } from 'react-native';
    
    export interface Spec extends TurboModule {
        // your module methods go here, for example:
        add(a: number, b: number): Promise<number>;
    }
    export default (TurboModuleRegistry.get<Spec>(
        'RNCalculator'
    ): ?Spec);
  1. Open the calculator/package.json
  2. Add the following snippet at the end of it:
    ,
    "codegenConfig": {
        "name": "RNCalculatorSpec",
        "type": "modules",
        "jsSrcsDir": "src",
        "android": {
            "javaPackageName": "com.rnnewarchitecturelibrary"
        }
    }
  1. Open the calculator/android/build.gradle file and update the code as follows:
    + def isNewArchitectureEnabled() {
    +    return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
    +}
    
    apply plugin: 'com.android.library'
    +if (isNewArchitectureEnabled()) {
    +    apply plugin: 'com.facebook.react'
    +}
    
    // ... other parts of the build file
    
    dependencies {
        implementation 'com.facebook.react:react-native:+'
    }
    
  1. Open the calculator/calculator.podspec file
  2. Before the Pod::Spec.new do |s| add the following code:
    folly_version = '2021.07.22.00'
    folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
  3. Before the end tag, add the following code
    # This guard prevent to install the dependencies when we run `pod install` in the old architecture.
    if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
        s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
        s.pod_target_xcconfig    = {
            "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
            "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
        }
    
        s.dependency "React-Codegen"
        s.dependency "RCT-Folly", folly_version
        s.dependency "RCTRequired"
        s.dependency "RCTTypeSafety"
        s.dependency "ReactCommon/turbomodule/core"
    end
  1. In the ios/RNCalculator folder, rename the RNCalculator.m into RNCalculator.mm
  2. Open it and replace its content with:
    #import "RNCalculator.h"
    // Thanks to this guard, we won't import this header when we build for the old architecture.
    #ifdef RCT_NEW_ARCH_ENABLED
    #import "RNCalculatorSpec.h"
    #endif
    
    @implementation RNCalculator
    
    RCT_EXPORT_MODULE()
    
    RCT_REMAP_METHOD(add, addA:(NSInteger)a
                            andB:(NSInteger)b
                    withResolver:(RCTPromiseResolveBlock) resolve
                    withRejecter:(RCTPromiseRejectBlock) reject)
    {
      return [self add:a b:b resolve:resolve reject:reject];
    }
    
    // Thanks to this guard, we won't compile this code when we build for the old architecture.
    #ifdef RCT_NEW_ARCH_ENABLED
    - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
        (const facebook::react::ObjCTurboModule::InitParams &)params
    {
        return std::make_shared<facebook::react::NativeCalculatorSpecJSI>(params);
    }
    #endif
    
    - (void)add:(double)a b:(double)b resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
      NSNumber *result = [[NSNumber alloc] initWithInteger:a+b];
      resolve(result);
    }
    
    @end
  3. Open the ios/RNCalculator.h file and replace its content with:
    #import <Foundation/Foundation.h>
    
    #ifdef RCT_NEW_ARCH_ENABLED
    
    #import <RNCalculatorSpec/RNCalculatorSpec.h>
    @interface RNCalculator: NSObject <NativeCalculatorSpec>
    
    #else
    
    #import <React/RCTBridgeModule.h>
    @interface RNCalculator : NSObject <RCTBridgeModule>
    
    #endif
    
    @end
  1. Open the calculator/android/src/main/java/com/rnnewarchitecturelibrary/CalculatorModule.java and modify it as it follows:
    public class CalculatorModule extends ReactContextBaseJavaModule {
    
    +    public static final String NAME = "RNCalculator";
    
        CalculatorModule(ReactApplicationContext context) {
            super(context);
        }
    
        @Override
        public String getName() {
    -       return "Calculator";
    +       return NAME;
        }
  2. Open the calculator/android/src/main/java/com/rnnewarchitecturelibrary/CalculatorPackage.java and replace its content with:
    package com.rnnewarchitecturelibrary;
    
    import androidx.annotation.Nullable;
    import com.facebook.react.bridge.NativeModule;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.module.model.ReactModuleInfo;
    import com.facebook.react.module.model.ReactModuleInfoProvider;
    import com.facebook.react.TurboReactPackage;
    import com.facebook.react.uimanager.ViewManager;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.HashMap;
    import java.util.Map;
    
    public class CalculatorPackage extends TurboReactPackage {
    
        @Nullable
        @Override
        public NativeModule getModule(String name, ReactApplicationContext reactContext) {
            if (name.equals(CalculatorModule.NAME)) {
                return new CalculatorModule(reactContext);
            } else {
                return null;
            }
        }
    
        @Override
        public ReactModuleInfoProvider getReactModuleInfoProvider() {
            return () -> {
                final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
                moduleInfos.put(
                        CalculatorModule.NAME,
                        new ReactModuleInfo(
                                CalculatorModule.NAME,
                                CalculatorModule.NAME,
                                false, // canOverrideExistingModule
                                false, // needsEagerInit
                                true, // hasConstants
                                false, // isCxxModule
                                false // isTurboModule
                ));
                return moduleInfos;
            };
        }
    }

About

A collection of sample React Native Libraries that will show you how to use the New Architecture (Fabric & TurboModules) step-by-step.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published