Step‑by‑Step Guide: Embedding V8 and Node.js into a C++ Game Server

This article walks through embedding the V8 JavaScript engine into a C++ game server, demonstrates a HelloWorld example, shows how to bind C++ classes using Puerts, and explains how to compile and embed a full Node.js runtime, with complete code snippets and a GitHub repository link.

Tencent Cloud Developer
Tencent Cloud Developer
Tencent Cloud Developer
Step‑by‑Step Guide: Embedding V8 and Node.js into a C++ Game Server

HelloWorld Example

This minimal example shows how to embed the V8 JavaScript engine into a Linux C++ program. The implementation is split into six logical blocks:

Block 1 : Define a Print callback that extracts the first argument from the V8 FunctionCallbackInfo and writes it to std::cout.

Block 2 : Initialise V8, create a snapshot blob, set up the default platform and initialise the V8 engine.

Block 3 : Create an Isolate, an Isolate::Scope, a HandleScope and a new execution Context.

Block 4 : Register the Print function as a global JavaScript function in the context.

Block 5 : Compile a short script that calls Print('hello world') and execute it.

Block 6 : Dispose the isolate, shut down the platform and clean up allocated resources.

The complete source code (without styling attributes) can be compiled with any standard C++ tool‑chain:

static void Print(const v8::FunctionCallbackInfo<v8::Value>& info) {
    v8::Isolate* isolate = info.GetIsolate();
    v8::String::Utf8Value utf8(isolate, info[0]);
    std::cout << *utf8 << std::endl;
}

int main(int argc, char* argv[]) {
    // Initialise V8
    v8::V8::InitializeICUDefaultLocation(argv[0]);
    v8::V8::InitializeExternalStartupData(argv[0]);
    std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
    v8::V8::InitializePlatform(platform.get());
    v8::V8::Initialize();

    // Create a new Isolate
    v8::Isolate::CreateParams create_params;
    create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
    v8::Isolate* isolate = v8::Isolate::New(create_params);

    {
        v8::Isolate::Scope isolate_scope(isolate);
        v8::HandleScope handle_scope(isolate);
        v8::Local<v8::Context> context = v8::Context::New(isolate);
        v8::Context::Scope context_scope(context);

        // Register Print
        context->Global()->Set(context,
            v8::String::NewFromUtf8(isolate, "Print").ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, Print)->GetFunction(context).ToLocalChecked()
        ).Check();

        // Compile and run script
        const char* source = "Print('hello world');";
        v8::Local<v8::String> src = v8::String::NewFromUtf8(isolate, source).ToLocalChecked();
        v8::Local<v8::Script> script = v8::Script::Compile(context, src).ToLocalChecked();
        script->Run(context);
    }

    // Cleanup
    isolate->Dispose();
    v8::V8::Dispose();
    v8::V8::ShutdownPlatform();
    delete create_params.array_buffer_allocator;
    return 0;
}

Binding C++ Classes with Puerts

Puerts provides a lightweight bridge that lets C++ classes be exposed to JavaScript (or TypeScript) without writing manual glue code. The following TestClass demonstrates constructor, static method, instance method, and property binding:

class TestClass {
public:
    TestClass(int p) { std::cout << "TestClass(" << p << ")" << std::endl; X = p; }
    static void Print(const std::string& msg) { std::cout << msg << std::endl; }
    int Add(int a, int b) { std::cout << "Add(" << a << "," << b << ")" << std::endl; return a + b; }
    int X;
};

// Register the class with Puerts
usingCppType(TestClass);
puerts::DefineClass<TestClass>()
    .Constructor<int>()
    .Function("Print", MakeFunction(&TestClass::Print))
    .Method("Add", MakeFunction(&TestClass::Add))
    .Property("X", MakeProperty(&TestClass::X))
    .Register();

In JavaScript the class can be loaded and used as follows:

const TestClass = loadCppType('TestClass');
TestClass.Print('hello world');
let obj = new TestClass(123);
TestClass.Print(obj.X);
obj.X = 99;
TestClass.Print(obj.X);
TestClass.Print('ret = ' + obj.Add(1, 3));

Embedding a Full Node.js Runtime

When the full Node.js ecosystem (e.g., setTimeout, npm packages) is required, the guide shows how to build a shared library libnode.so from the Node.js source and link it with a small embedding program that also includes V8, libuv and Node headers.

Build libnode.so

./configure --shared
make -j4
# The resulting library is out/Release/libnode.so.95

Compile the embedding test program (example command, paths may need adjustment):

c++ -I./src -I./deps/v8/include -I./deps/uv/include \
    embedtest.cc -c -o embedtest.o
c++ embedtest.o -Wl,-rpath,./out/Release \
    -L./out/Release -lnode.so.95 -o embedtest

Running the program with a simple script demonstrates that both the custom C++ class (registered via Puerts) and native Node.js APIs are available:

.\/embedtest "console.log('hello world')"

Example JavaScript used in the embedded Node.js environment:

const TestClass = loadCppType('TestClass');
TestClass.Print('hello world');
let obj = new TestClass(123);
TestClass.Print(obj.X);
obj.X = 99;
TestClass.Print(obj.X);
TestClass.Print('ret = ' + obj.Add(1, 3));
const fs = require('fs');
let info = fs.readdirSync('.');
console.log(info);

Embedding Node.js introduces an event loop and additional threads; developers should verify that this does not conflict with the existing server framework.

All source code, build scripts and a detailed README are available in the GitHub repository:

https://github.com/chexiongsheng/v8_embedding_test

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptNode.jsCEmbeddingV8ScriptingPuertsgame server
Tencent Cloud Developer
Written by

Tencent Cloud Developer

Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.