How to call C/C++ code from Node.js

It might be NOT that hard as you think! Let’s see you can you can call C/C++ code or use a native library from a Node.js app.

Node.js ❤ C/C++

Q: Why would I need to call C/C++ code? There is half a million NPM modules, why would I need native stuff at all?

A: It you don’t need any C/C++ interop right now, it doesn’t mean you won’t need it in the future. In large apps there is usually a mix of different programming languages and technologies is used, you don’t want to limit yourself to working with a single stack, but instead, choose the right tool for the job.

Consider, for example, a password hashing function that is used during sign in process. It’s takes at least 200ms to calculate a hash string, by design! You don’t want to make it run on the same thread where your Node.js app is running, at least, not in a production environment.

The process looks as follows. You create a file with some C++ code (it may call some 3rd party library), place configuration file in the root of your project, telling what exactly needs to be compiled natively (more on that later), add flag to , run (or, ). It will compile your C++ code into a file, that later on can be referenced from inside JavaScript code and used as if it was a regular JavaScript module. You don’t even need the module installed globally (or, locally) for that, because npm (or, yarn) can use the built-in node-gyp library to compile your code.

This thingy is called an “addon” in Node.js terminology.

Node.js Addons are dynamically-linked shared objects, written in C++, that can be loaded into Node.js using the require() function, and used just as if they were an ordinary Node.js module. They are used primarily to provide an interface between JavaScript running in Node.js and C/C++ libraries.

Hello World

Let’s start by rewriting the following piece of JavaScript code into C++:

Assuming that you already have a sandox project with a Node.js app, create two files in the root of your project — and with the following content:

binding.cpp

binding.gyp

Also, update file in the root of your project to include flag and dependency:

The field in file is used to tell npm/yarn under what name to save the compiled output file. In our case it will be saved into .

The field contains the list of C/C++ source files that need to be compiled. If you add another or file, don’t forget to append it to that list.

The , , , in the file are C++ wrapper classes over Node’s C API (aka N-API) imported from the namespace (notice at the top of the file). If you’re curious, you can find their implementations inside of the nodejs/node-addon-api project on GitHub (see napi.h for example). The actual source files from “node-addon-api” helper module are referenced in the and fields in the file.

Now, after building the project via (or, you must be able to call your native module from JavaScript. The only gotcha is that “node-addon-api” is still an experimental feature and works only under flag. So you can execute it as follows:

There is one more useful library called that allows importing Node.js addons without providing the full path-name to the file. Install it by running , then you’ll be able to reference our native module as follows:

Using a native C/C++ library from Node.js

Now, let’s call some 3rd party library from under our native module (addon). I’d like to believe that you develop your Node.js apps inside Docker containers. As an example, let’s install Sodium crypto library and try to call its methods from our file. In Docker container you can install it as follows:

The , and modules are used in order to be able to compile C/C++ code inside container, and is the library itself that we will use. In development mode you would use as it comes with the source files and in production mode you would install .

Now let’s update file to reference as follows:

Now you can reference at the top of the file and try to call some of the libsodium’s methods. We’re going to use function in our example that converts a password string into a hash using Argon2 password hashing algorithm:

Now, after running you can run this code in Node:

There is a little bit more work to make this code work asynchronously, but it’s still pretty easy to do. You can find a working example here:

in the Node.js API Starter project on GitHub.

Summary

Calling C/C++ code using modern N-API interface in combination with C++ wrappers () is almost too easy to be true. I hope the code samples above demonstrate the point. Just try to avoid using old APIs and approaches, e.g. Nan, using C instead of C++, and you’ll be good :)

Happy coding!

Bringing the technical edge to early-stage companies with advice on software architecture, best practices, database design, web infrastructure, and DevOps.