How to create a native add-on using C++
Tags: cpp
Published: 2021-07-29 08:53:17

> This article was published on Monday, May 8, 2017 by [Eytan Manor](https://twitter.com/eytan_manor) @ [The Guild Blog](https://the-guild.dev/)

In this tutorial we're going to go through the basics on how to write a native add-on to NodeJS
using C++, one of the platform's most powerful capabilities of which most web/JS developers now a
days are not even familiar with.

For somewhat there is a vacuum which got created around C++ in the recent years, people are so
scared from a low-level back-end programming, why should they even deal with memory allocation
dilemmas when there are all these interpretation languages like Python, Ruby, and JavaScript who can
do that for us? Well folks, once you will realize that all these single web-page application
third-party libraries and frameworks are all recycled and repetitive, and you will start doing some
real shit by optimizing some heavy-ass machine algorithms, you will realize that performance is
critic, a title which doesn't really suit NodeJS, with all the love and respect. So why do I even
bother making this tutorial? Because people are unaware of many features in the programming world,
and the beauty of algorithmics. And why am I even approaching NodeJS developers? Because they have
the biggest, most-popular community of all, they have a lot to learn, but they are very open-minded,
and that's the most important thing. You don't have to be a C++ developer not at all, but if I can
at least catch a small part of your attention I will be overwhelmed.

We will create a very small and simple module which calculates the distance between two dots, it can
do it either synchronously or asynchronously. The algorithm for calculating the distance between a
given `pointA` and `pointB` in a 2D
[Cartesian coordinate system](https://en.wikipedia.org/wiki/Cartesian_coordinate_system) looks like
this:

```
√[(pointAX - pointBX)^2 + (pointAY - pointBY)^2]
```

Probably not too complicated, kicks me back to the glamorous days in high-school. If put in
JavaScript it should take around 10 seconds right? Well in a native NodeJS add-on it should be a bit
longer. Of-course when it comes to small logics you shouldn't make too much effort, because it will
consume more power only converting all JS objects into C++ native structures. But imagine you would
like to run a [blob-detection](https://en.wikipedia.org/wiki/Blob_detection) algorithm and you would
like to calculate the [center of mass](https://en.wikipedia.org/wiki/Center_of_mass) of multiple
blobs, in C++ it would be much faster, especially when using
[shaders](https://en.wikipedia.org/wiki/Shader). Anyway that's not the point of this tutorial, the
point is that you will be provided with the necessary tools so next time if you would like to write
some heavy logic, you will know how to do it.

We will start with a brief introduction for Google's
[v8 engine](https://en.wikipedia.org/wiki/V8_\(JavaScript_engine\)) and some practical examples on
how to use it, this will help us to get start, and then we will write our add-on. Let's begin then
shall we?

***

## Introduction to V8

![](https://the-guild.dev/medium/6989c5ee48f37336c330100619adbe13.png)

The v8 JavaScript Engine is an open source JavaScript engine developed by The
[Chromium Project](https://chromium.org) for the
[Google Chrome web browser](https://google.com/chrome). It is intended to be used both in a browser
and as a standalone high-performance engine that can be integrated into independent projects like
[Couchbase](http://couchbase.com), [MongoDB](https://mongodb.com) and [Node.js](https://nodejs.org).
There lots of benchmarks out there but I will not bore you with diagrams, we all know that this
engine has proven itself to be worthy, and it is being used world-widely and probably for a good
reason.

> *“Ambition is a dream with a v8 engine” -Elvis Presley.*

If you're a JavaScript developer you must be familiar with the event-loop and the scoping system of
v8, so it's a good thing that you understand the concept, but you never got to actually look at its
source code and explicitly use it. A detailed documentation for v8's different API versions is
available [here](https://v8docs.nodesource.com). I assume that you don't bother reading any of my
references that I provide along this tutorial (As a lazy blog-reader myself), I will post here that
first thing you're going to see once you enter v8's documentation web-site:

![](https://the-guild.dev/medium/e2b532f4bd546a9c1bdb1cb2022fbd80.jpg)

Throughout history v8 have changed a lot, and it wore many forms. As a result, add-ons are not
usable across different versions of the platform since each one supports a different API, which will
break our process during run-time. In NodeJS team they came up with a very convenient solution
called [Nan](https://github.com/nodejs/nan). Nan stands for “Native Abstractions for NodeJS” and is
basically a header file filled with macro and utility goodness for making add-on development for
NodeJS easier across all versions of v8, without inspecting `NODE_MODULE_VERSION` macro all the
time. In this tutorial I'm going to refer both of them as if they are bundled in a single framework.

Eventually JavaScript is just a rehash of v8, everything you know so far is still valid, but it uses
a different idiom. To prevent some misconceptions, here are some important points regards
JavaScript's equivalents which I think you should follow:

### Scopes and Variables

In v8 a scope is referred as `Isolate` (`v8::Isolate`) and a variable is referred as `Local`
(`v8::Local`). A local is a pointer to an object. All v8 objects are accessed using locals, they are
necessary because of the way the v8 garbage collector works. An isolate can be thought of as a
container for any number of locals. When you've finished with your locals, instead of deleting each
one individually you can simply delete their scope.

**JavaScript**

```javascript
let obj = {
  foo: 'foo',
  bar: 'bar',
  baz: 'baz'
}
```

```javascript
console.log(obj.foo)
console.log(obj.bar)
console.log(obj.baz)
```

**C++**

```cpp
using Nan::New;
using std::cendl;
using std::cout;
using v8::Local;
using v8::Object;
using v8::String;

Local<Object> obj = New<Object>();

obj->Set(New<String>("foo").ToLocalChecked(), New<String>("foo").ToLocalChecked());
obj->Set(New<String>("bar").ToLocalChecked(), New<String>("bar").ToLocalChecked());
obj->Set(New<String>("baz").ToLocalChecked(), New<String>("baz").ToLocalChecked());

cout << obj->Get(New<String>("foo").ToLocalChecked()) << cendl;
cout << obj->Get(New<String>("bar").ToLocalChecked()) << cendl;
cout << obj->Get(New<String>("baz").ToLocalChecked()) << cendl;
```

### Asynchronous Callbacks

Asynchronous logic can be implemented using the `AsyncWorker` (`Nan::AsyncWorker`) and invoked by
`AsyncQueueWorker` (`Nan::AsyncQueueWorker`). Thanks to these two you can have much of the annoying
asynchronous queuing and handling taken care of for you. It can even store arbitrary V8 objects for
you and have them persist while the asynchronous work is in progress.

**JavaScript**

```javascript
setImmediate(() => {
  callback(null, 'result')
})
```

**C++**

```cpp
using Nan::AsyncQueueWorker;
using Nan::AsyncWorker;
using Nan::HandleScope;
using Nan::New;
using Nan::Null;
using std::string;
using v8::Local;
using v8::String;

class ResultWorker : AsyncWorker {
 private:
  string* result

 public:
  ResultWorker(Callback* callback) : AsyncWorker(callback) {}

  ~ResultDistance() {
    delete result;
  }

  // Executed inside the worker-thread.
  // It is not safe to access V8, or V8 data structures
  // here, so everything we need for input and output
  // should go on 'this'.
  void Execute () {
    result = new string("result");
  }

  // Executed when the async work is complete.
  // This function will be run inside the main event loop
  // so it is safe to use V8 again.
  void HandleOKCallback () {
    HandleScope scope;
    Local<Value> argv[] = {
      Null(),
      New<String>(result).ToLocalChecked()
    };
    callback->Call(2, argv);
  }
};

AsyncQueueWorker(new ResultWorker(callback));
```

### Modules Registration and Methods Definition

v8 and Nan provide us with some handy macros (`NODE_MODULE`, `NAN_MODULE_INIT`, `NAN_METHOD` and
`NODE_SET_METHOD`) which will help us register a new NodeJS module and define its methods. This
might be confusing for some, since we can't see the function's signature it would appear as if
variables are just being magically created in the stack, but once the macros are being pre-processed
they will just turn into ordinary functions. In the example below I commented the original signature
so you can have more clew on what's going on.

**JavaScript**

```javascript
exports.fn = (a, b) => a + b
```

**C++**

```cpp
using Nan::To;
using v8::Local;
using v8::Object;

// void Fn(FunctionCallbackInfo<Value>& info)
NAN_METHOD(Fn) {
  double a = To<double>(info[0]).FromJust();
  double b = To<double>(info[1]).FromJust();

  info.GetReturnValue().Set(a + b);
}

// void Init(Local<Object> target)
NAN_MODULE_INIT(Init) {
  NODE_SET_METHOD(target, Fn);
}

// First argument would be the entry file's name
NODE_MODULE(addon, Init);
```

As you can see when dealing with v8 explicitly is a time-consuming process which requires you to do
lots of extra-work. With that said, keep in mind that only a small portion of your code is going to
interact with the engine since the core logic should be written using native C++ and other
third-party libraries. You always need to find the right balance. Always make sure that your add-on
doesn't require too much data to be passed otherwise the conversion process is gonna be hard and
inefficient, and think twice before you choose this approach for the sake of simplicity. Overall the
estimated optimization should be around 150% and up, depends on the task, first check your
JavaScript code snippet, check for unnecessary logic and optimize it, and if you're really sure that
it is fully optimized, and you're still striving for more performance, *only then* move to C++.

So far I went through the very basics which will help you create this bridge between the two
platforms. The v8 lacks of detailed documentation, tutorials and examples.
[Nan](https://github.com/nodejs/nan) however is a bit more documented IMHO, so when I approach the
API documentation I would start from there, and if I didn't find anything useful I would look at
v8's [latest API docs](https://v8docs.nodesource.com). It's not a hard material to learn but it's
different, so it might be a bit challenging for some, but remember, practice practice practice.

Speaking of practice, let's move on to the next step where we going to implement our first add-on
for distance calculation between two points.

***

## Creating the Add-On

In this step we will base our development process on the TDD methodology, so you will have a chance
to look at the final target API that we desire. We will start by writing a test file:

### [Add Test File](https://github.com/DAB0mB/node-distance-addon/commit/823f652)

**Added `.npmignore`**

```diff
+┊ ┊1┊test.js
```

**Added `test.js`**

```diff
+┊  ┊ 1┊const Distance = require('.');
+┊  ┊ 2┊
+┊  ┊ 3┊let result;
+┊  ┊ 4┊let pointA = { x: 0, y: 0 };
+┊  ┊ 5┊let pointB = { x: 3, y: 4 };
+┊  ┊ 6┊
+┊  ┊ 7┊result = Distance.calculate.sync(pointA, pointB);
+┊  ┊ 8┊
+┊  ┊ 9┊if (result !== 5) throw Error(
+┊  ┊10┊  '#Sync: Result expected to equal 5 but instead got ' + result
+┊  ┊11┊);
+┊  ┊12┊
+┊  ┊13┊console.log('sync calculation passed');
+┊  ┊14┊
+┊  ┊15┊result = Distance.calculate.async(pointA, pointB, (err, result) => {
+┊  ┊16┊  if (err) throw err;
+┊  ┊17┊
+┊  ┊18┊  if (result !== 5) throw Error(
+┊  ┊19┊    '#Async: Result expected to equal 5 but instead got ' + result
+┊  ┊20┊  );
+┊  ┊21┊
+┊  ┊22┊  console.log('async calculation passed');
+┊  ┊23┊});🚫↵
```

And the following NPM script should execute it:

### [Add npm Test Script](https://github.com/DAB0mB/node-distance-addon/commit/35b20fd)

**Changed package.json**

```diff
 ┊ 6┊ 6┊  "repository": {
 ┊ 7┊ 7┊    "type": "git",
 ┊ 8┊ 8┊    "url": "https://github.com/DAB0mB/node-distance-addon.git"
+┊  ┊ 9┊  },
+┊  ┊10┊  "scripts": {
+┊  ┊11┊    "test": "node test"
 ┊ 9┊12┊  }
 ┊10┊13┊}
```

Like I said in the introduction, it's a simple module which can calculate the distance between 2
given points. `calculate.sync` can do it synchronously and `calculate.async` can do it
asynchronously. Now that you got the idea we will start configuring our add-on.

The first thing you'll need to do is to make sure that you have `node-gyp` installed:

```bash
sudo npm install -g node-gyp
```

`node-gyp` is also dependent on many other packages, so before you go any further please take a look
at the official installation instructions in their
[README.md file](https://github.com/nodejs/node-gyp).

Assuming that you have installed everything properly, we will now need to create a `binding.gyp`
file:

### [Create `binding.gyp` File](https://github.com/DAB0mB/node-distance-addon/commit/ff44399)

**Added `binding.gyp`**

```diff
+┊  ┊ 1┊{
+┊  ┊ 2┊  "targets": [
+┊  ┊ 3┊    {
+┊  ┊ 4┊      "target_name": "distance",
+┊  ┊ 5┊      "sources": [
+┊  ┊ 6┊        "src/distance.cc"
+┊  ┊ 7┊      ],
+┊  ┊ 8┊      "include_dirs": ["<!(node -e \"require('nan')\")"]
+┊  ┊ 9┊    }
+┊  ┊10┊  ]
+┊  ┊11┊}🚫↵
```

GYP stands for 'Generate Your Project' and was created by the Chromium team as a configuration file
for building native projects. The configuration show above should be a good template for any future
add-on you're looking to develop. Let's take a deeper look at it:

*   `target_name` - Specifies the output dir of our add-on, in which case it should be
    `build/Release/distance`
*   `sources` - Should include all the cpp files that are associated with you add-on.
*   `include_dirs` - Additional dirs that should be included when building the add-on. If you'll run
    the given script in the terminal you'll get the node-module path for Nan, a library which we're
    interested in during the build process.

More information about GYP configuration can be found
[here](https://gyp.gsrc.io/docs/UserDocumentation.md).

Be sure to also add the specified flag to the `package.json` which basically says 'Hey, I have a GYP
file which should be taken into consideration as well':

### [Create `binding.gyp` File](https://github.com/DAB0mB/node-distance-addon/commit/ff44399)

**Changed `package.json`**

```diff
 ┊ 7┊ 7┊    "type": "git",
 ┊ 8┊ 8┊    "url": "https://github.com/DAB0mB/node-distance-addon.git"
 ┊ 9┊ 9┊  },
+┊  ┊10┊  "gypfile": true,
 ┊10┊11┊  "scripts": {
 ┊11┊12┊    "test": "node test"
 ┊12┊13┊  }
```

Now we will add the following NPM scripts so whenever we run `npm run build` our project will be
built:

### [Add npm Build Scripts](https://github.com/DAB0mB/node-distance-addon/commit/a9a8815)

**Changed `.gitignore`**

```diff
+┊ ┊1┊build
 ┊1┊2┊node_modules🚫↵
```

**Changed `package.json`**

```diff
 ┊ 9┊ 9┊  },
 ┊10┊10┊  "gypfile": true,
 ┊11┊11┊  "scripts": {
+┊  ┊12┊    "pre-publish": "npm run build",
+┊  ┊13┊    "build": "node-gyp rebuild",
+┊  ┊14┊    "test": "npm run build && node test"
 ┊13┊15┊  }
 ┊14┊16┊}
```

The only thing left to do before jumping into implementation would be installing Nan:

```bash
npm install nan --save
```

The basis for build process is set. We will create the entry file for our add-on:

### [Create Add-On Entry File](https://github.com/DAB0mB/node-distance-addon/commit/793e892)

**Added `src/distance.cc`**

```diff
+┊ ┊1┊#include <nan.h>
+┊ ┊2┊#include <v8.h>
+┊ ┊3┊
+┊ ┊4┊NAN_MODULE_INIT(Init) {
+┊ ┊5┊
+┊ ┊6┊}
+┊ ┊7┊
+┊ ┊8┊NODE_MODULE(distance, Init)🚫↵
```

Every add-on should start with these two macro calls. They are both compiled into a piece of code
which will register our module with ease. The `NODE_MODULE` macro template accepts the name of the
target as the first argument (That one we set as `target_name` in the GYP file, remember?) and the
initialization method for our module. The `NAN_MODULE_INIT`generates a function with the given name.
It accepts `target` as the first argument which is equivalent to Node.js' `exports`. Now we will
create our first method stub for a synchronous distance calculation:

### [Create `CalculateSync` Method Stub](https://github.com/DAB0mB/node-distance-addon/commit/90e3c72)

**Changed `src/distance.cc`**

```diff
 ┊ 1┊ 1┊#include <nan.h>
 ┊ 2┊ 2┊#include <v8.h>
 ┊ 3┊ 3┊
+┊  ┊ 4┊NAN_METHOD(CalculateSync) {
+┊  ┊ 5┊
+┊  ┊ 6┊}
 ┊ 5┊ 7┊
+┊  ┊ 8┊NAN_MODULE_INIT(Init) {
+┊  ┊ 9┊  NAN_EXPORT(target, CalculateSync);
 ┊ 6┊10┊}
 ┊ 7┊11┊
 ┊ 8┊12┊NODE_MODULE(distance, Init)🚫↵
```

We exported the `CalculateSync` by using the `NAN_EXPORT` macro, and we used `NAN_METHOD` to define
a new node-valid function. It accepts `info` as the first argument, and it is the same as
JavaScript's `arguments` vector. We already know which arguments this function should accept, that's
why I followed TDD methodology from the first place:

### [Destructure Arguments Vector](https://github.com/DAB0mB/node-distance-addon/commit/ee1d560)

**Changed `src/distance.cc`**

```diff
 ┊ 1┊ 1┊#include <nan.h>
 ┊ 2┊ 2┊#include <v8.h>
 ┊ 3┊ 3┊
+┊  ┊ 4┊using Nan::To;
+┊  ┊ 5┊using v8::Local;
+┊  ┊ 6┊using v8::Object;
 ┊ 5┊ 7┊
+┊  ┊ 8┊NAN_METHOD(CalculateSync) {
+┊  ┊ 9┊  Local<Object> js_pointA = To<Object>(info[0]).ToLocalChecked();
+┊  ┊10┊  Local<Object> js_pointB = To<Object>(info[1]).ToLocalChecked();
 ┊ 6┊11┊}
 ┊ 7┊12┊
 ┊ 8┊13┊NAN_MODULE_INIT(Init) {
```

We use the `To()` function to convert the first argument into the desired type, and then we call the
method `ToLocalChecked()`. This method is simply going to convert the result into v8's Local, unless
the argument is undefined, in which case an error is going to be thrown. I like to prefix JS object
with a `js_` so I know with what kind variable I'm dealing with. We should have two points
containing `x` and `y` fields. Let's try to extract them out of the arguments vector and convert
them into native C++ structures:

### [Convert JS Objects to Native C++ Structures](https://github.com/DAB0mB/node-distance-addon/commit/81998eb)

**Changed `src/distance.cc`**

```diff
 ┊ 1┊ 1┊#include <nan.h>
 ┊ 2┊ 2┊#include <v8.h>
 ┊ 3┊ 3┊
+┊  ┊ 4┊using Nan::New;
 ┊ 4┊ 5┊using Nan::To;
 ┊ 5┊ 6┊using v8::Local;
 ┊ 6┊ 7┊using v8::Object;
+┊  ┊ 8┊using v8::String;
+┊  ┊ 9┊
+┊  ┊10┊struct Point {
+┊  ┊11┊  double x;
+┊  ┊12┊  double y;
+┊  ┊13┊};
 ┊ 7┊14┊
 ┊ 8┊15┊NAN_METHOD(CalculateSync) {
 ┊ 9┊16┊  Local<Object> js_pointA = To<Object>(info[0]).ToLocalChecked();
 ┊10┊17┊  Local<Object> js_pointB = To<Object>(info[1]).ToLocalChecked();
+┊  ┊18┊
+┊  ┊19┊  Point* pointA = new Point();
+┊  ┊20┊  pointA->x = To<double>(js_pointA->Get(New<String>("x").ToLocalChecked())).FromJust();
+┊  ┊21┊  pointA->y = To<double>(js_pointA->Get(New<String>("y").ToLocalChecked())).FromJust();
+┊  ┊22┊
+┊  ┊23┊  Point* pointB = new Point();
+┊  ┊24┊  pointB->x = To<double>(js_pointB->Get(New<String>("x").ToLocalChecked())).FromJust();
+┊  ┊25┊  pointB->y = To<double>(js_pointB->Get(New<String>("y").ToLocalChecked())).FromJust();
 ┊11┊26┊}
 ┊12┊27┊
 ┊13┊28┊NAN_MODULE_INIT(Init) {
```

Then again we convert the `To()` function to convert the result into the desired data-type, only
this time it's a primitive, so we use `FromJust()` instead of `ToLocalChecked()`. Note that v8 only
uses double precision rather than a floating point. We can fetch properties from a given JS object
with ease using the `Get()` method. Pay attention to use the `->` rather than a period because
remember, a Local is actually a pointer! It is not the actual object.

Now all is left to do is defining the return value. Keep in mind that the value should be returned
through v8's current scope, not natively, so using the `return` keyword would be useless. The return
value can actually be defined through the provided `info` argument, like this:

### [Add Return Value to `CalculateSync` Method](https://github.com/DAB0mB/node-distance-addon/commit/1d6a7f6)

**Changed `src/distance.cc`**

```diff
 ┊23┊23┊  Point* pointB = new Point();
 ┊24┊24┊  pointB->x = To<double>(js_pointB->Get(New<String>("x").ToLocalChecked())).FromJust();
 ┊25┊25┊  pointB->y = To<double>(js_pointB->Get(New<String>("y").ToLocalChecked())).FromJust();
+┊  ┊26┊
+┊  ┊27┊  info.GetReturnValue().Set(CalculateDistance(pointA, pointB));
 ┊26┊28┊}
 ┊27┊29┊
 ┊28┊30┊NAN_MODULE_INIT(Init) {
```

And of-course it requires us to add the core distance calculation method:

### [Add Core Distance Calculation Method](https://github.com/DAB0mB/node-distance-addon/commit/5af3b3d)

**Changed `src/distance.cc`**

```diff
+┊  ┊ 1┊#include <cstdlib>
+┊  ┊ 2┊#include <cmath>
 ┊ 1┊ 3┊#include <nan.h>
 ┊ 2┊ 4┊#include <v8.h>
 ┊ 3┊ 5┊
 ┊ 4┊ 6┊using Nan::New;
 ┊ 5┊ 7┊using Nan::To;
+┊  ┊ 8┊using std::pow;
+┊  ┊ 9┊using std::sqrt;
 ┊ 6┊10┊using v8::Local;
 ┊ 7┊11┊using v8::Object;
 ┊ 8┊12┊using v8::String;
```

```diff
 ┊12┊16┊  double y;
 ┊13┊17┊};
 ┊14┊18┊
+┊  ┊19┊double CalculateDistance(Point* pointA, Point* pointB) {
+┊  ┊20┊  return sqrt(pow(pointA->x - pointB->x, 2) + pow(pointA->y - pointB->y, 2));
+┊  ┊21┊}
+┊  ┊22┊
 ┊15┊23┊NAN_METHOD(CalculateSync) {
 ┊16┊24┊  Local<Object> js_pointA = To<Object>(info[0]).ToLocalChecked();
 ┊17┊25┊  Local<Object> js_pointB = To<Object>(info[1]).ToLocalChecked();
```

This is it for the synchronous calculation. Now we will add an async version of it. We will start by
creating a method with everything we learned so far until the point where we have to return the
result:

### [Create `CalculateAsync` Method with Basic Deconstructuring](https://github.com/DAB0mB/node-distance-addon/commit/2711bf5)

**Changed `src/distance.cc`**

```diff
 ┊35┊35┊  info.GetReturnValue().Set(CalculateDistance(pointA, pointB));
 ┊36┊36┊}
 ┊37┊37┊
+┊  ┊38┊NAN_METHOD(CalculateAsync) {
+┊  ┊39┊  Local<Object> js_pointA = To<Object>(info[0]).ToLocalChecked();
+┊  ┊40┊  Local<Object> js_pointB = To<Object>(info[1]).ToLocalChecked();
+┊  ┊41┊
+┊  ┊42┊  Point* pointA = new Point();
+┊  ┊43┊  pointA->x = To<double>(js_pointA->Get(New<String>("x").ToLocalChecked())).FromJust();
+┊  ┊44┊  pointA->y = To<double>(js_pointA->Get(New<String>("y").ToLocalChecked())).FromJust();
+┊  ┊45┊
+┊  ┊46┊  Point* pointB = new Point();
+┊  ┊47┊  pointB->x = To<double>(js_pointB->Get(New<String>("x").ToLocalChecked())).FromJust();
+┊  ┊48┊  pointB->y = To<double>(js_pointB->Get(New<String>("y").ToLocalChecked())).FromJust();
+┊  ┊49┊}
+┊  ┊50┊
 ┊38┊51┊NAN_MODULE_INIT(Init) {
 ┊39┊52┊  NAN_EXPORT(target, CalculateSync);
+┊  ┊53┊  NAN_EXPORT(target, CalculateAsync);
 ┊40┊54┊}
 ┊41┊55┊
 ┊42┊56┊NODE_MODULE(distance, Init)🚫↵
```

Here's the different part. We don't wanna simply return the value, we want to make the calculations
in parallel with the event loop, and once we're finished we will interact with it once again. In our
model there are two threads. The first thread is the event loop thread, and the second thread will
be a worker thread managed by Nan, the library supports asynchronous I/O in NodeJS. Let's start
implementing and I will give some more explanations as we go further:

### [Queue Distance Worker](https://github.com/DAB0mB/node-distance-addon/commit/34f4a5d)

**Changed `src/distance.cc`**

```diff
 ┊ 3┊ 3┊#include <nan.h>
 ┊ 4┊ 4┊#include <v8.h>
 ┊ 5┊ 5┊
+┊  ┊ 6┊using Nan::AsyncQueueWorker;
+┊  ┊ 7┊using Nan::AsyncWorker;
+┊  ┊ 8┊using Nan::Callback;
 ┊ 6┊ 9┊using Nan::New;
 ┊ 7┊10┊using Nan::To;
 ┊ 8┊11┊using std::pow;
 ┊ 9┊12┊using std::sqrt;
+┊  ┊13┊using v8::Function;
 ┊10┊14┊using v8::Local;
 ┊11┊15┊using v8::Object;
 ┊12┊16┊using v8::String;
```

```diff
 ┊38┊42┊NAN_METHOD(CalculateAsync) {
 ┊39┊43┊  Local<Object> js_pointA = To<Object>(info[0]).ToLocalChecked();
 ┊40┊44┊  Local<Object> js_pointB = To<Object>(info[1]).ToLocalChecked();
+┊  ┊45┊  Callback* callback = new Callback(info[2].As<Function>());
 ┊41┊46┊
 ┊42┊47┊  Point* pointA = new Point();
 ┊43┊48┊  pointA->x = To<double>(js_pointA->Get(New<String>("x").ToLocalChecked())).FromJust();
```

```diff
 ┊46┊51┊  Point* pointB = new Point();
 ┊47┊52┊  pointB->x = To<double>(js_pointB->Get(New<String>("x").ToLocalChecked())).FromJust();
 ┊48┊53┊  pointB->y = To<double>(js_pointB->Get(New<String>("y").ToLocalChecked())).FromJust();
+┊  ┊54┊
+┊  ┊55┊  AsyncQueueWorker(new DistanceWorker(callback, pointA, pointB));
 ┊49┊56┊}
 ┊50┊57┊
 ┊51┊58┊NAN_MODULE_INIT(Init) {
```

Here we fetch the third argument which is the callback. We wrap it with Nan's Callback, which will
make sure it is not garbage collected once the scope is being deleted, we want it to keep living
until it's not relevant. At the bottom of the method, instead of returning a value explicitly, we
queue our `DistanceWorker` into the workers queue. On that note, let's implement the DistanceWorker:

### [Create `DistanceWorker` with a Constructor and a Deconstructor](https://github.com/DAB0mB/node-distance-addon/commit/8bbd87f)

**Changed `src/distance.cc`**

```diff
 ┊24┊24┊  return sqrt(pow(pointA->x - pointB->x, 2) + pow(pointA->y - pointB->y, 2));
 ┊25┊25┊}
 ┊26┊26┊
+┊  ┊27┊class DistanceWorker : public AsyncWorker {
+┊  ┊28┊ private:
+┊  ┊29┊  Point* pointA;
+┊  ┊30┊  Point* pointB;
+┊  ┊31┊
+┊  ┊32┊ public:
+┊  ┊33┊  DistanceWorker(Callback* callback, Point* pointA, Point* pointB) :
+┊  ┊34┊    AsyncWorker(callback), pointA(pointA), pointB(pointB) {}
+┊  ┊35┊
+┊  ┊36┊  ~DistanceWorker() {
+┊  ┊37┊    delete pointA;
+┊  ┊38┊    delete pointB;
+┊  ┊39┊  }
+┊  ┊40┊
+┊  ┊41┊  void Execute () {
+┊  ┊42┊
+┊  ┊43┊  }
+┊  ┊44┊
+┊  ┊45┊  void HandleOKCallback () {
+┊  ┊46┊
+┊  ┊47┊  }
+┊  ┊48┊};
+┊  ┊49┊
 ┊27┊50┊NAN_METHOD(CalculateSync) {
 ┊28┊51┊  Local<Object> js_pointA = To<Object>(info[0]).ToLocalChecked();
 ┊29┊52┊  Local<Object> js_pointB = To<Object>(info[1]).ToLocalChecked();
```

`AsyncWorker` is an abstract class that you can subclass to have much of the annoying asynchronous
queuing and handling taken care of for you. It can even store arbitrary v8 objects for you and have
them persist while the asynchronous work is in progress. The `execute()` method is being executed
inside the worker-thread. It is not safe to access V8, or V8 data structures there, so everything we
need for input and output should go on 'this'. The `HandleOKCallback()` method is executed when the
async work is complete. This function will be run inside the main event loop, so it is safe to use
v8 again. Let's implement the core distance calculation on the worker thread:

### [Execute Distance Calculation](https://github.com/DAB0mB/node-distance-addon/commit/9cd18e8)

**Changed `src/distance.cc`**

```diff
 ┊26┊26┊
 ┊27┊27┊class DistanceWorker : public AsyncWorker {
 ┊28┊28┊ private:
+┊  ┊29┊  double distance;
 ┊29┊30┊  Point* pointA;
 ┊30┊31┊  Point* pointB;
 ┊31┊32┊
```

```diff
 ┊39┊40┊  }
 ┊40┊41┊
 ┊41┊42┊  void Execute () {
+┊  ┊43┊    distance = CalculateDistance(pointA, pointB);
 ┊43┊44┊  }
 ┊44┊45┊
 ┊45┊46┊  void HandleOKCallback () {
```

And handle a successful invocation once the calculation is finished:

### [Handle Successful Invokation](https://github.com/DAB0mB/node-distance-addon/commit/8dd60ff)

**Changed `src/distance.cc`**

```diff
 ┊ 6┊ 6┊using Nan::AsyncQueueWorker;
 ┊ 7┊ 7┊using Nan::AsyncWorker;
 ┊ 8┊ 8┊using Nan::Callback;
+┊  ┊ 9┊using Nan::HandleScope;
 ┊ 9┊10┊using Nan::New;
+┊  ┊11┊using Nan::Null;
 ┊10┊12┊using Nan::To;
 ┊11┊13┊using std::pow;
 ┊12┊14┊using std::sqrt;
 ┊13┊15┊using v8::Function;
 ┊14┊16┊using v8::Local;
+┊  ┊17┊using v8::Number;
 ┊15┊18┊using v8::Object;
 ┊16┊19┊using v8::String;
+┊  ┊20┊using v8::Value;
 ┊17┊21┊
 ┊18┊22┊struct Point {
 ┊19┊23┊  double x;
```

```diff
 ┊44┊48┊  }
 ┊45┊49┊
 ┊46┊50┊  void HandleOKCallback () {
+┊  ┊51┊    HandleScope scope;
 ┊47┊52┊
+┊  ┊53┊    Local<Value> argv[] = {
+┊  ┊54┊      Null(),
+┊  ┊55┊      New<Number>(distance)
+┊  ┊56┊    };
+┊  ┊57┊
+┊  ┊58┊    callback->Call(2, argv);
 ┊48┊59┊  }
 ┊49┊60┊};
```

Normally, when defining a NodeJS method (`NAN_METHOD` macro) a scope will be created for us
automatically. In this function's context there is no scope exist, so we will have to create it
using the `HandleScope` deceleration (The current scope is stored globally so even though we don't
use it explicitly, v8 and Nan know what to do). We also created an arguments vector as the return
value, following Node.js' conventions, the first argument would be the error and the second argument
would be the result.

This is it! Finally, we will transform the add-on into a nicer looking node-module:

### [Transform Add-On into a Nicer Looking Node Module](https://github.com/DAB0mB/node-distance-addon/commit/a250013)

**Added `index.js`**

```
+┊ ┊1┊const Distance = require('./build/Release/distance');
+┊ ┊2┊
+┊ ┊3┊exports.calculate = {
+┊ ┊4┊  sync: Distance.CalculateSync,
+┊ ┊5┊  async: Distance.CalculateAsync
+┊ ┊6┊};🚫↵
```

And now, let's run our small test to see that it works, using the following command:

```bash
npm run test
```

If everything went well, you should have the following messages printed to the terminal:

```
sync calculation passed
async calculation passed
```

***

## What's Next?

You've just learned the very basics of how to use C++ within NodeJS. There's a lot more to learn
when it comes to building an add-on, and I'm not just talking about learning v8 and Nan's API. Think
about the possibilities, the C++ community have been developed for years and there are so much great
libraries out there that are not necessarily relevant to NodeJS due to its efficiency, like
[Boost](http://boost.org), [OpenCV](http://opencv.org), [CGAL](http://cgal.org) and many more.

*   Check out the full project of this tutorial:
    [https://github.com/DAB0mB/node-distance-addon](https://github.com/DAB0mB/node-distance-addon)
*   Check out this awesome framework for creating tutorials by Urigo, which helped me to make this
    nicely structured tutorial: [https://github.com/Urigo/tortilla](https://github.com/Urigo/tortilla)