0.25.1 • Published 12 months ago

react-native-nitro-modules v0.25.1

Weekly downloads
-
License
MIT
Repository
github
Last release
12 months ago

react-native-nitro-modules is a core library that contains highly efficient statically compiled JS to C++ bindings.

It uses JSI to generate C++ templates that can bridge virtually any JS type to a C++ type with minimal overhead.

Installation

Inside an app

Install react-native-nitro-modules as a dependency in your react-native app:

npm i react-native-nitro-modules
cd ios && pod install

Inside a nitro module library

If you are building a nitro module yourself, add react-native-nitro-modules as a peerDependency into your library's package.json:

{
  ...
  "peerDependencies": {
    ...
    "react-native-nitro-modules": "*"
  },
}

Then install react-native-nitro-modules as a normal dependency in your library's example/ app as seen above.

Usage

react-native-nitro-modules can either be used with-, or without nitrogen, or mixed (some objects are automatically generated, some manually).

With Nitrogen

When using Nitrogen, all the bindings are automatically generated. You only need to implement C++, Swift or Kotlin interfaces inside your codebase.

Without Nitrogen

All C++ bindings are bridged to JS using "Hybrid Objects".

A Hybrid Object can have both methods and properties (get and set). Create a C++ Hybrid Object by inheriting from HybridObject:

#include <NitroModules/HybridObject.hpp>

using namespace margelo::nitro;

class MyHybridObject: public HybridObject {
public:
  explicit MyHybridObject(): HybridObject(TAG) {}

public:
  // Property (get)
  double getNumber() { return 13; }
  // Property (set)
  void setNumber(double value) { }
  // Method
  double add(double left, double right) { return left + right; }

public:
  void loadHybridMethods() override {
    // Call base method to make sure we properly inherit `toString()` and `equals()`
    HybridObject::loadHybridMethods();
    // Register all methods that need to be exposed to JS
    registerHybrids(this, [](Prototype& prototype) {
      prototype.registerHybridGetter("number", &MyHybridObject::getNumber);
      prototype.registerHybridSetter("number", &MyHybridObject::setNumber);
      prototype.registerHybridMethod("add", &MyHybridObject::add);
    });
  }

private:
  static constexpr auto TAG = "MyHybrid";
};

The MyHybridObject can then be registered in the HybridObjectRegistry at app startup:

#include <NitroModules/HybridObjectRegistry.hpp>

// Call this at app startup to register the HybridObjects
void load() {
  HybridObjectRegistry::registerHybridObjectConstructor(
    "MyHybrid",
    []() -> std::shared_ptr<HybridObject> {
      return std::make_shared<MyHybridObject>();
    }
  );
}

Inside your MyHybridObject, you can use standard C++ types which will automatically be converted to JS using Nitro's JSIConverter<T> interface.

The following C++ / JS types are supported out of the box:

Since the JSIConverter<T> is just a template, you can extend it with any other custom types by overloading the interface.

For example, to add support for an enum, overload JSIConverter<MyEnum>:

#include <NitroModules/JSIConverter.hpp>

enum class MyEnum {
  FIRST = 0,
  SECOND = 1
};

namespace margelo::nitro {
  template <>
  struct JSIConverter<MyEnum> {
    static inline MyEnum fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
      int intValue = JSIConverter<int>::fromJSI(runtime, arg);
      return static_cast<MyEnum>(intValue);
    }
    static inline jsi::Value toJSI(jsi::Runtime& runtime, MyEnum arg) {
      int intValue = static_cast<int>(arg);
      return JSIConverter<int>::toJSI(runtime, intValue);
    }
  };
}

Once the JSIConverter<T> for MyEnum is defined, you can use the type MyEnum in C++ methods, getters and setters of HybridObjects.

And on the JS side, you can simply treat the returned number (int) as a MyEnum:

enum MyEnum {
  FIRST = 0,
  SECOND = 1
}
const value = myHybridObject.getEnumValue() // <-- typed as `MyEnum` instead of `number`

Make sure to always include the header that defines the JSIConverter<MyEnum> overload inside the MyHybridObject file, as this is where the JSIConverter<T> overloads are accessed from.

Nitrogen can automatically generate such JSIConverter<T> extensions for enums, TypeScript unions, and even structs/objects - so it is generally recommended to use nitrogen.

0.21.0

1 year ago

0.20.1

1 year ago

0.20.0

1 year ago

0.19.0

1 year ago

0.18.1

1 year ago

0.18.2

1 year ago

0.15.0

1 year ago

0.14.1

1 year ago

0.16.0

1 year ago

0.17.0

1 year ago

0.16.1

1 year ago

0.18.0

1 year ago

0.16.2

1 year ago

0.25.1

12 months ago

0.25.0

12 months ago

0.24.1

12 months ago

0.24.0

12 months ago

0.23.0

1 year ago

0.22.1

1 year ago

0.22.0

1 year ago

0.14.0

1 year ago

0.11.0

1 year ago

0.12.0

1 year ago

0.13.0

1 year ago

0.10.0

1 year ago

0.9.0

1 year ago

0.8.0

1 year ago

0.9.2

1 year ago

0.9.1

1 year ago

0.7.0

1 year ago

0.6.0

1 year ago

0.5.0

2 years ago

0.4.1

2 years ago

0.4.0

2 years ago

0.3.0

2 years ago

0.2.0

2 years ago

0.1.7

2 years ago

0.1.6

2 years ago

0.1.5

2 years ago

0.1.4

2 years ago

0.1.3

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.4

2 years ago

0.0.2

2 years ago