Since we released Node.js for Mobile Apps, the most requested feature has been support for Node.js native modules (also known as “C++ Addons”). This makes sense, since it is common for an npm module to either contain some native code itself or have a dependency on a module that does.
So we have been working hard to tackle this challenge. We are now excited to announce that support for native modules is available in the latest release of the React Native and Cordova plugins.
Being able to use these modules strengthens compatibility of Node.js for Mobile Apps with the npm module ecosystem, and opens a lot of possibilities for building mobile applications with Node.js.
How to start using native modules with Node.js for Mobile Apps
With the latest release of nodejs-mobile-react-native and nodejs-mobile-cordova, the plugins automatically detect the existence of native modules inside the
nodejs-project folder in your app, and take care of building and packaging them as part of the application build process. It just works!
Node.js native modules and their challenges for mobile
Node.js native modules are Node.js packages that contain native code and instructions on how to build that native code using node-gyp. When installing a native module from npm, the default behavior is for the module to be built for the system on which npm is currently running. This makes sense when using Node.js on the server/desktop, where we can expect the required build tools to be available on the system, or for the module to be prebuilt and copied from a similar system. On mobile, however, this is either not practical or (on iOS) downright impossible; so we had to modify a few things to enable native modules to get cross-compiled and packaged with the application.
To that end, the plugins are using a modified version of node-gyp that is able to target the right OS and CPU architecture and include the Node.js headers from the Node.js for Mobile Apps release.
On iOS, we also need to ensure that the module binaries are packaged as a Framework signed with the application’s signing identity and loaded from the application’s /Frameworks path, which is required for loading dynamic libraries and for being accepted in the iOS App Store. Many thanks to Patrick Chugh, for all his help in validating iOS App Store submission with the Shango App.
On Android, we have to build a standalone toolchain before we can cross-compile native modules, and that needs to be done for each ABI supported by the application. We are able to support Universal APKs by packaging binaries for all the supported ABIs, and then choosing which binary to load at runtime.
Special care is also needed for modules the use node-pre-gyp to download a prebuilt binary, to ensure that they are actually built on the current machine and for the target OS and architecture.
All of that and more is handled automatically by the plugins, so developers don’t even need to worry about whether their app uses native modules or not.
Limitations and future work
Our goal was to ensure that as many existing native modules as possible work without modification on mobile. However, Node.js native modules are so flexible that it is not feasible to support every possible scenario. Modules that have non-standard build steps (e.g. depending on shell scripts rather than node-gyp, for building) may require further changes to work on mobile. Modules with platform-specific code or dependencies might need porting of that code to iOS or Android.
Given the large number of native modules out there, it would probably take our team a very long time to test and try to solve all the possible compatibility issues. So this is an area where we hope to get a lot of help from the community. To that end, we have created a GitHub repository where the community can discuss compatibility issues of existing modules with nodejs-mobile.
There are also other improvements to be made:
- Adding support for building native modules for Android on Windows development machines (currently only macOS and Linux are supported).
- Providing an easy way to use native modules in applications that are not using the
- Being able to use an installed NDK instead of building a standalone NDK toolchain for Android.
A whole new world of possibilities
Having native modules opens a whole new world of possibilities for using Node.js for Mobile Apps. Our community Gitter channel has been filled with questions and experiments on this topic. We can’t wait to see what sort of novel and creative applications can be developed now that native modules are supported out of the box.
We invite you to try using Node.js with native modules in your mobile applications, and to get involved with the project. Provide feedback, report bugs, suggest improvements, contribute code. Go build amazing new apps and radically new frameworks with it!
To get started, visit the Node.js for Mobile Apps website.