Nostalgic Pizza Manager


    1.8.1 • Public • Published

    Build status NPM Join the chat at


    Header-only library to expose C++ classes and functions into V8 to use them in JavaScript code. v8pp requires a compiler with C++14 support. The library has been tested on:

    • Microsoft Visual C++ 2019 (Windows 10)
    • GCC 5.4.0 (Ubuntu 16.04)
    • Clang 5.0.0 (Ubuntu 16.04)

    Building and testing

    The library has a set of tests that can be configured, built, and run with CMake:

    ~/v8pp$ mkdir out; cd out
    ~/v8pp/out$ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON ..
    ~/v8pp/out$ make
    ~/v8pp/out$ ctest -V

    The full list of project options can be listed with cmake command:

    ~/v8pp/out$ cmake -LH ..

    Some of them could be:

    // Build documentation BUILD_DOCUMENTATION:BOOL=OFF

    // Build shared library BUILD_SHARED_LIBS:BOOL=ON

    // Build and run tests BUILD_TESTING:BOOL=OFF

    // Header-only library V8PP_HEADER_ONLY:BOOL=0

    // v8::Isolate data slot number, used in v8pp for shared data V8PP_ISOLATE_DATA_SLOT:STRING=0

    // v8pp plugin initialization procedure name V8PP_PLUGIN_INIT_PROC_NAME:STRING=v8pp_module_init

    // v8pp plugin filename suffix V8PP_PLUGIN_SUFFIX:STRING=.dylib

    // Use std::string_view V8PP_USE_STD_STRING_VIEW:BOOL=0


    Binding example

    v8pp supports V8 versions after 6.3 with v8::Isolate usage in API. There are 2 targets for binding:

    • v8pp::module, a wrapper class around v8::ObjectTemplate
    • v8pp::class_, a template class wrapper around v8::FunctionTemplate

    Both of them require a pointer to v8::Isolate instance. They allows to bind from C++ code such items as variables, functions, constants with a function set(name, item):

    v8::Isolate* isolate;
    int var;
    int get_var() { return var + 1; }
    void set_var(int x) { var = x + 1; }
    struct X
        X(int v, bool u) : var(v) {}
        int var;
        int get() const { return var; }
        void set(int x) { var = x; } 
    // bind free variables and functions
    v8pp::module mylib(isolate);
        // set read-only attribute
        .set_const("PI", 3.1415)
        // set variable available in JavaScript with name `var`
        .set("var", var)
        // set function get_var as `fun`
        .set("fun", &get_var)
        // set property `prop` with getter get_var() and setter set_var()
        .set("prop", property(get_var, set_var));
    // bind class
    v8pp::class_<X> X_class(isolate);
        // specify X constructor signature
        .ctor<int, bool>()
        // bind variable
        .set("var", &X::var)
        // bind function
        .set("fun", &X::set)
        // bind read-only property
        .set("prop", property(&X::get));
    // set class into the module template
    mylib.set("X", X_class);
    // set bindings in global object as `mylib`
        v8::String::NewFromUtf8(isolate, "mylib"), mylib.new_instance());

    After that bindings will be available in JavaScript:

    mylib.var = mylib.PI +;
    var x = new mylib.X(1, true);
    mylib.prop = x.prop +;

    Node.js and io.js addons

    The library is suitable to make Node.js and io.js addons. See addons document.

    void RegisterModule(v8::Local<v8::Object> exports)
        v8pp::module addon(v8::Isolate::GetCurrent());
        // set bindings... 
            .set("fun", &function)
            .set("cls", my_class)
        // set bindings as exports object prototype

    v8pp also provides

    • v8pp - a static library to add several global functions (load/require to the v8 JavaScript context. require() is a system for loading plugins from shared libraries.
    • test - A binary for running JavaScript files in a context which has v8pp module loading functions provided.

    v8pp module example

    #include <iostream>
    #include <v8pp/module.hpp>
    namespace console {
    void log(v8::FunctionCallbackInfo<v8::Value> const& args)
        v8::HandleScope handle_scope(args.GetIsolate());
        for (int i = 0; i < args.Length(); ++i)
            if (i > 0) std::cout << ' ';
            v8::String::Utf8Value str(args[i]);
            std::cout <<  *str;
        std::cout << std::endl;
    v8::Local<v8::Value> init(v8::Isolate* isolate)
        v8pp::module m(isolate);
        m.set("log", &log);
        return m.new_instance();
    } // namespace console

    Turning a v8pp module into a v8pp plugin

    V8PP_PLUGIN_INIT(v8::Isolate* isolate)
        return console::init(isolate);

    v8pp class binding example

    #include <v8pp/module.hpp>
    #include <v8pp/class.hpp>
    #include <fstream>
    namespace file {
    bool rename(char const* src, char const* dest)
        return std::rename(src, dest) == 0;
    class file_base
        bool is_open() const { return stream_.is_open(); }
        bool good() const { return stream_.good(); }
        bool eof() const { return stream_.eof(); }
        void close() { stream_.close(); }
        std::fstream stream_;
    class file_writer : public file_base
        explicit file_writer(v8::FunctionCallbackInfo<v8::Value> const& args)
            if (args.Length() == 1)
                v8::String::Utf8Value str(args[0]);
        bool open(char const* path)
  , std::ios_base::out);
            return stream_.good();
        void print(v8::FunctionCallbackInfo<v8::Value> const& args)
            v8::HandleScope scope(args.GetIsolate());
            for (int i = 0; i < args.Length(); ++i)
                if (i > 0) stream_ << ' ';
                v8::String::Utf8Value str(args[i]);
                stream_ << *str;
        void println(v8::FunctionCallbackInfo<v8::Value> const& args)
            stream_ << std::endl;
    class file_reader : public file_base
        explicit file_reader(char const* path)
        bool open(const char* path)
  , std::ios_base::in);
            return stream_.good();
        v8::Local<v8::Value> getline(v8::Isolate* isolate)
            if ( stream_.good() && ! stream_.eof())
                std::string line;
                std::getline(stream_, line);
                return v8pp::to_v8(isolate, line);
                return v8::Undefined(isolate);
    v8::Local<v8::Value> init(v8::Isolate* isolate)
        v8::EscapableHandleScope scope(isolate);
        // file_base binding, no .ctor() specified, object creation disallowed in JavaScript
        v8pp::class_<file_base> file_base_class(isolate);
            .set("close", &file_base::close)
            .set("good", &file_base::good)
            .set("is_open", &file_base::is_open)
            .set("eof", &file_base::eof)
        // .ctor<> template arguments declares types of file_writer constructor
        // file_writer inherits from file_base_class
        v8pp::class_<file_writer> file_writer_class(isolate);
            .ctor<v8::FunctionCallbackInfo<v8::Value> const&>()
            .set("open", &file_writer::open)
            .set("print", &file_writer::print)
            .set("println", &file_writer::println)
        // .ctor<> template arguments declares types of file_reader constructor.
        // file_base inherits from file_base_class
        v8pp::class_<file_reader> file_reader_class(isolate);
            .ctor<char const*>()
            .set("open", &file_reader::open)
            .set("getln", &file_reader::getline)
        // Create a module to add classes and functions to and return a
        // new instance of the module to be embedded into the v8 context
        v8pp::module m(isolate);
        m.set("rename", &rename)
         .set("writer", file_writer_class)
         .set("reader", file_reader_class)
        return scope.Escape(m.new_instance());
    } // namespace file
    V8PP_PLUGIN_INIT(v8::Isolate* isolate)
        return file::init(isolate);

    Creating a v8 context capable of using require() function

    #include <v8pp/context.hpp>
    v8pp::context context;
    // script can now use require() function. An application
    // that uses v8pp::context must link against v8pp library.
    v8::HandleScope scope(context.isolate());

    Using require() from JavaScript

    // Load the file module from the class binding example and the
    // console module.
    var file    = require('file'),
        console = require('console')
    var writer = new file.writer("file")
    if (writer.is_open()) {
        writer.println("some text")
        if (! file.rename("file", "newfile"))
            console.log("could not rename file")
    else console.log("could not open `file'")

    Create a handle to an externally referenced C++ class.

    // Memory for C++ class will remain when JavaScript object is deleted.
    // Useful for classes you only wish to inject.
    typedef v8pp::class_<my_class> my_class_wrapper;
    v8::Local<v8::Value> val = my_class_wrapper::reference_external(isolate, &my_class::instance());
    // Assuming my_class::instance() returns reference to class

    Import externally created C++ class into v8pp.

    // Memory for c++ object will be reclaimed by JavaScript using "delete" when
    // JavaScript class is deleted.
    typedef v8pp::class_<my_class> my_class_wrapper;
    v8::Local<v8::Value> val = my_class_wrapper::import_external(isolate, new my_class);

    Compile-time configuration

    The library uses several preprocessor macros, defined in v8pp/config.hpp file:

    • V8PP_ISOLATE_DATA_SLOT - A v8::Isolate data slot number, used to store v8pp internal data
    • V8PP_PLUGIN_INIT_PROC_NAME - Plugin initialization procedure name that should be exported from a v8pp plugin.
    • V8PP_PLUGIN_SUFFIX - Plugin filename suffix that would be added if the plugin name used in require() doesn't end with it.
    • V8PP_HEADER_ONLY - Use header-only implemenation, enabled by default.

    v8pp alternatives


    npm i v8pp

    DownloadsWeekly Downloads






    Unpacked Size

    277 kB

    Total Files


    Last publish


    • pmed