How to write a React Native CxxModule

Kudo Chien
3 min readNov 5, 2018

--

CxxModule is a feature rarely mentioned in React Native that you could write Native Module directly with C++. Especially on Android, it is really a pain to write a JNI wrapper to do marshaling between C++ and Java. Besides, the performance should be better because the bridge call is happening purely between JSVM and C++, no JVM involved. If you want to write a Native Module and your existing code is C++, you should definitely try CxxModule.
I will introduce CxxModule on Android as example, since C++ interop used to be easier for Obj-C.

How to write a CxxModule

There is a sample in React Native code base that somebody may already knows. I also wrote a simple example on GitHub.

To export methods for JavaScript, override getMethods():

Export foo() method for JavaScript that will accept a callback with “foo”

To export constants for JavaScript, override getConstants():

Export constants for JavaScript

To emit JS event from C++, callJSFunction() for RCTDeviceEventEmitter.emit() is possible:

CxxModule exports method bar() that will send JS event to simulate AppState changes

For more, please check CxxModule.h for details, E.g. how to export a method that will return a Promise.

After go through the CxxModule how to, there is also an important part and seems nobody mentioned in Internet — How to register a CxxModule to package.

There is a CxxModuleWrapper.java which is the simplest way to register if your Native Module are all pure in C++. Otherwise, if you need hybrid case, e.g. the code will be called both from JS and Java, please refer to Hybrid class.
Let’s go back for CxxModuleWrapper.makeDso() which accept two parameters: one for shared library filename and the other for exported entry function to create a CxxModule instance.

Here is the code:

Now you may know some basic shape of CxxModule. Let’s go for the most difficult part.

Build Process

I think this part is the most difficult to adopt CxxModule for OSS React Native. It may be the reason that nobody talked about CxxModule usage.

In the code above, you may see that CxxModule heavily relies on Folly . It means you need Folly to build the CxxModule into shared library (lib*.so on Android). Folly depends on some other 3rd party libraries such as boost and glog. Even though we don’t need to rebuild the libraries, we still need the headers to build our CxxModule.B̵a̵s̵i̵c̵a̵l̵l̵y̵,̵ ̵t̵h̵e̵ ̵p̵r̵o̵c̵e̵s̵s̵ ̵a̵r̵e̵ ̵p̵r̵e̵t̵t̵y̵ ̵m̵u̵c̵h̵ ̵l̵i̵k̵e̵ ̵b̵u̵i̵l̵d̵i̵n̵g̵ ̵R̵e̵a̵c̵t̵ ̵N̵a̵t̵i̵v̵e̵ ̵A̵n̵d̵r̵o̵i̵d̵ ̵f̵r̵o̵m̵ ̵s̵o̵u̵r̵c̵e̵ ̵c̵o̵d̵e̵.̵ ̵I̵ ̵w̵i̵l̵l̵ ̵n̵o̵t̵ ̵g̵o̵ ̵t̵h̵r̵o̵u̵g̵h̵ ̵b̵r̵i̵e̵f̵l̵y̵ ̵h̵o̵w̵ ̵t̵o̵ ̵b̵u̵i̵l̵d̵.̵ ̵P̵l̵e̵a̵s̵e̵ ̵c̵h̵e̵c̵k̵ ̵b̵u̵i̵l̵d̵.̵g̵r̵a̵d̵l̵e̵ ̵f̵r̵o̵m̵ ̵m̵y̵ ̵s̵a̵m̵p̵l̵e̵ ̵p̵r̵o̵j̵e̵c̵t̵ ̵h̵e̵r̵e̵ ̵a̵n̵d̵ ̵t̵h̵e̵ ̵s̵a̵m̵p̵l̵e̵ ̵n̵d̵k̵b̵u̵i̵l̵d̵ ̵A̵n̵d̵r̵o̵i̵d̵.̵m̵k̵
̵T̵o̵ ̵l̵i̵n̵k̵ ̵C̵x̵x̵M̵o̵d̵u̵l̵e̵ ̵w̵i̵t̵h̵ ̵R̵e̵a̵c̵t̵ ̵N̵a̵t̵i̵v̵e̵ ̵p̵r̵e̵b̵u̵i̵l̵t̵ ̵l̵i̵b̵r̵a̵r̵i̵e̵s̵,̵ ̵I̵ ̵e̵x̵t̵r̵a̵c̵t̵ ̵t̵h̵e̵ ̵t̵h̵e̵ ̵J̵N̵I̵ ̵f̵i̵l̵e̵s̵ ̵f̵r̵o̵m̵ ̵r̵e̵a̵c̵t̵-̵n̵a̵t̵i̵v̵e̵ ̵A̵A̵R̵.̵ ̵S̵e̵e̵ ̵g̵r̵a̵d̵l̵e̵ ̵p̵r̵e̵p̵a̵r̵e̵E̵x̵t̵r̵a̵c̵t̵e̵d̵L̵i̵b̵s̵ ̵t̵a̵s̵k̵ ̵f̵o̵r̵ ̵d̵e̵t̵a̵i̵l̵.̵

Update: I’ve update the sample to React Native 0.60.4 based and to keep patching build.gradle easier, I turned to build React Native Android AAR from source code. The two commits are all of it:

  1. Build RN from source
  2. Add CxxModule

Summary

Overall, you could check the commit that includes all the changes to add a HelloCxxModule.

It takes some extra work indeed. But if your codebase are most written by C++, the extra work are worth to do. At my company when we did the Puffin Browser on Windows, since React Native Windows does not support CxxModule, we turned to write a lot of wrapping code. For example, to export a native module method, we should do

  • Wrap our C++ code to C
  • Wrap the method in C# and do PInvoke to C function in DLL.
  • Optionally to wrap the method from JavaScript to NativeModules.foo.

If you are developing an Android app, the JNI wrapper will not be easier.
CxxModule will save you from lots of boilerplate wrapper code.

On the other hand, the next React Native architecture — Fabric, there is a new JSI design, which seems support to register JS functions directly into JS VM. I guess life will be easier then.

At last, please let me promote our product — Puffin Browser on Windows.
It is wicked fast and will not have performance pain if you have mass opening tabs.

--

--