Node.js addon hello world

We’re going to make a native extension called addon. Here’s main.js, which uses this extension:

// main.js
const addon = require('./addon');
console.log(addon.hello());

And here it is in action:

$ node main.js
world

Now, you could implement addon in JavaScript, like this:

// addon.js
module.exports.hello = () => 'world';

But instead, we’re going to implement addon in C++ as a Node.js addon! Instead of a file called addon.js, we’ll be making addon.node. The extension .node tells Node.js that it’s a native module, not a JavaScript module.

These .node files can be built with a tool called node-gyp:

$ npm install -g node-gyp

To use it, first create the following binding.gyp file:

# binding.gyp
{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "addon_src.cc" ]
    }
  ]
}

Then run node-gyp configure, which uses the above binding.gyp file. Our binding.gyp says we’re going to build addon.node from the source file addon_src.cc. Make that next:

// addon_src.cc
#include <node.h>

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::String;
using v8::Value;

void Method(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  args.GetReturnValue().Set(String::NewFromUtf8(
      isolate, "world", NewStringType::kNormal).ToLocalChecked());
}

void Initialize(Local<Object> exports) {
  NODE_SET_METHOD(exports, "hello", Method);
}

NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)

With everything in place, we can build our addon.node file with node-gyp build:

$ node-gyp build
$ cp build/Release/addon.node .
$ node main.js  # uses addon.node!
world

Get updates on Twitter


More by Jim

Tagged #programming. All content copyright James Fisher 2019. This post is not associated with my employer. Found an error? Edit this page.