{
  "type": "module",
  "source": "doc/api/embedding.md",
  "modules": [
    {
      "textRaw": "C++ embedder API",
      "name": "c++_embedder_api",
      "introduced_in": "v12.19.0",
      "type": "module",
      "desc": "<p>Node.js provides a number of C++ APIs that can be used to execute JavaScript\nin a Node.js environment from other C++ software.</p>\n<p>The documentation for these APIs can be found in <a href=\"https://github.com/nodejs/node/blob/HEAD/src/node.h\">src/node.h</a> in the Node.js\nsource tree. In addition to the APIs exposed by Node.js, some required concepts\nare provided by the V8 embedder API.</p>\n<p>Because using Node.js as an embedded library is different from writing code\nthat is executed by Node.js, breaking changes do not follow typical Node.js\n<a href=\"deprecations.html\">deprecation policy</a> and may occur on each semver-major release without prior\nwarning.</p>",
      "modules": [
        {
          "textRaw": "Example embedding application",
          "name": "example_embedding_application",
          "type": "module",
          "desc": "<p>The following sections will provide an overview over how to use these APIs\nto create an application from scratch that will perform the equivalent of\n<code>node -e &#x3C;code></code>, i.e. that will take a piece of JavaScript and run it in\na Node.js-specific environment.</p>\n<p>The full code can be found <a href=\"https://github.com/nodejs/node/blob/HEAD/test/embedding/embedtest.cc\">in the Node.js source tree</a>.</p>",
          "modules": [
            {
              "textRaw": "Setting up a per-process state",
              "name": "setting_up_a_per-process_state",
              "type": "module",
              "desc": "<p>Node.js requires some per-process state management in order to run:</p>\n<ul>\n<li>Arguments parsing for Node.js <a href=\"cli.html\">CLI options</a>,</li>\n<li>V8 per-process requirements, such as a <code>v8::Platform</code> instance.</li>\n</ul>\n<p>The following example shows how these can be set up. Some class names are from\nthe <code>node</code> and <code>v8</code> C++ namespaces, respectively.</p>\n<pre><code class=\"language-cpp\">int main(int argc, char** argv) {\n  argv = uv_setup_args(argc, argv);\n  std::vector&#x3C;std::string> args(argv, argv + argc);\n  // Parse Node.js CLI options, and print any errors that have occurred while\n  // trying to parse them.\n  std::unique_ptr&#x3C;node::InitializationResult> result =\n      node::InitializeOncePerProcess(args, {\n        node::ProcessInitializationFlags::kNoInitializeV8,\n        node::ProcessInitializationFlags::kNoInitializeNodeV8Platform\n      });\n\n  for (const std::string&#x26; error : result->errors())\n    fprintf(stderr, \"%s: %s\\n\", args[0].c_str(), error.c_str());\n  if (result->early_return() != 0) {\n    return result->exit_code();\n  }\n\n  // Create a v8::Platform instance. `MultiIsolatePlatform::Create()` is a way\n  // to create a v8::Platform instance that Node.js can use when creating\n  // Worker threads. When no `MultiIsolatePlatform` instance is present,\n  // Worker threads are disabled.\n  std::unique_ptr&#x3C;MultiIsolatePlatform> platform =\n      MultiIsolatePlatform::Create(4);\n  V8::InitializePlatform(platform.get());\n  V8::Initialize();\n\n  // See below for the contents of this function.\n  int ret = RunNodeInstance(\n      platform.get(), result->args(), result->exec_args());\n\n  V8::Dispose();\n  V8::DisposePlatform();\n\n  node::TearDownOncePerProcess();\n  return ret;\n}\n</code></pre>",
              "displayName": "Setting up a per-process state"
            },
            {
              "textRaw": "Setting up a per-instance state",
              "name": "setting_up_a_per-instance_state",
              "type": "module",
              "meta": {
                "changes": [
                  {
                    "version": "v15.0.0",
                    "pr-url": "https://github.com/nodejs/node/pull/35597",
                    "description": "The `CommonEnvironmentSetup` and `SpinEventLoop` utilities were added."
                  }
                ]
              },
              "desc": "<p>Node.js has a concept of a “Node.js instance”, that is commonly being referred\nto as <code>node::Environment</code>. Each <code>node::Environment</code> is associated with:</p>\n<ul>\n<li>Exactly one <code>v8::Isolate</code>, i.e. one JS Engine instance,</li>\n<li>Exactly one <code>uv_loop_t</code>, i.e. one event loop,</li>\n<li>A number of <code>v8::Context</code>s, but exactly one main <code>v8::Context</code>, and</li>\n<li>One <code>node::IsolateData</code> instance that contains information that could be\nshared by multiple <code>node::Environment</code>s. The embedder should make sure\nthat <code>node::IsolateData</code> is shared only among <code>node::Environment</code>s that\nuse the same <code>v8::Isolate</code>, Node.js does not perform this check.</li>\n</ul>\n<p>In order to set up a <code>v8::Isolate</code>, an <code>v8::ArrayBuffer::Allocator</code> needs\nto be provided. One possible choice is the default Node.js allocator, which\ncan be created through <code>node::ArrayBufferAllocator::Create()</code>. Using the Node.js\nallocator allows minor performance optimizations when addons use the Node.js\nC++ <code>Buffer</code> API, and is required in order to track <code>ArrayBuffer</code> memory in\n<a href=\"process.html#processmemoryusage\"><code>process.memoryUsage()</code></a>.</p>\n<p>Additionally, each <code>v8::Isolate</code> that is used for a Node.js instance needs to\nbe registered and unregistered with the <code>MultiIsolatePlatform</code> instance, if one\nis being used, in order for the platform to know which event loop to use\nfor tasks scheduled by the <code>v8::Isolate</code>.</p>\n<p>The <code>node::NewIsolate()</code> helper function creates a <code>v8::Isolate</code>,\nsets it up with some Node.js-specific hooks (e.g. the Node.js error handler),\nand registers it with the platform automatically.</p>\n<pre><code class=\"language-cpp\">int RunNodeInstance(MultiIsolatePlatform* platform,\n                    const std::vector&#x3C;std::string>&#x26; args,\n                    const std::vector&#x3C;std::string>&#x26; exec_args) {\n  int exit_code = 0;\n\n  // Set up a libuv event loop, v8::Isolate, and Node.js Environment.\n  std::vector&#x3C;std::string> errors;\n  std::unique_ptr&#x3C;CommonEnvironmentSetup> setup =\n      CommonEnvironmentSetup::Create(platform, &#x26;errors, args, exec_args);\n  if (!setup) {\n    for (const std::string&#x26; err : errors)\n      fprintf(stderr, \"%s: %s\\n\", args[0].c_str(), err.c_str());\n    return 1;\n  }\n\n  Isolate* isolate = setup->isolate();\n  Environment* env = setup->env();\n\n  {\n    Locker locker(isolate);\n    Isolate::Scope isolate_scope(isolate);\n    HandleScope handle_scope(isolate);\n    // The v8::Context needs to be entered when node::CreateEnvironment() and\n    // node::LoadEnvironment() are being called.\n    Context::Scope context_scope(setup->context());\n\n    // Set up the Node.js instance for execution, and run code inside of it.\n    // There is also a variant that takes a callback and provides it with\n    // the `require` and `process` objects, so that it can manually compile\n    // and run scripts as needed.\n    // The `require` function inside this script does *not* access the file\n    // system, and can only load built-in Node.js modules.\n    // `module.createRequire()` is being used to create one that is able to\n    // load files from the disk, and uses the standard CommonJS file loader\n    // instead of the internal-only `require` function.\n    MaybeLocal&#x3C;Value> loadenv_ret = node::LoadEnvironment(\n        env,\n        \"const publicRequire =\"\n        \"  require('node:module').createRequire(process.cwd() + '/');\"\n        \"globalThis.require = publicRequire;\"\n        \"require('node:vm').runInThisContext(process.argv[1]);\");\n\n    if (loadenv_ret.IsEmpty())  // There has been a JS exception.\n      return 1;\n\n    exit_code = node::SpinEventLoop(env).FromMaybe(1);\n\n    // node::Stop() can be used to explicitly stop the event loop and keep\n    // further JavaScript from running. It can be called from any thread,\n    // and will act like worker.terminate() if called from another thread.\n    node::Stop(env);\n  }\n\n  return exit_code;\n}\n</code></pre>",
              "displayName": "Setting up a per-instance state"
            }
          ],
          "displayName": "Example embedding application"
        }
      ],
      "displayName": "C++ embedder API"
    }
  ]
}