CLI tool
nodejs/node-gyp avatar
nodejs/node-gyp

node-gyp: building Node.js native addons without the guesswork

Node.js native addon build tool

10,702 stars1,885 forksPythonMIT

At a glance

What is it?
node-gyp is the cross-platform build tool that turns a binding.gyp file into a compiled .node binary. It is the layer most Node.js users only meet when an npm install fails, and this article covers what it does, how to install it, and where it stops being the right answer.
Who is it for?
Adopt node-gyp if you ship a native addon or maintain a package with C or C++ sources, and if you can pin a toolchain on every machine that builds it. Do not adopt it if you only consume prebuilt binaries or want a compiler-free install path, because it pulls in Python, make and a platform C++ compiler before it can produce anything.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The failure mode node-gyp exists to remove

Any Node.js package with C or C++ sources has to be compiled on the machine that installs it, or shipped as a prebuilt binary for that exact platform and Node.js ABI. node-gyp is the tool that performs that compile. The README describes it as a cross-platform command-line tool written in Node.js for compiling native addon modules, built on a vendored copy of gyp-next, the build file generator the Chromium team previously used.

The audience is narrow and specific. Addon authors write a binding.gyp file and expect it to build on Linux, macOS and Windows without three separate build scripts. Package consumers meet node-gyp indirectly, when npm runs it during install and the compile fails. The tool's own README is explicit that node-gyp is not used to build Node.js itself, which is a common misreading.

The two features the README lists are the same build commands working on any supported platform, and the ability to target different versions of Node.js. That second one matters more than it sounds: an addon compiled against one Node.js ABI will not load in another, so the tool downloads the headers for the version you ask for rather than assuming the running interpreter.

How node-gyp turns binding.gyp into a .node file

The flow has three stages, and the README walks through all of them. First, configure reads binding.gyp in the current directory and generates platform build files. On Unix that is a Makefile; on Windows a vcxproj file. Both land in a build/ directory. Second, build invokes the platform toolchain against those generated files. Third, the linker emits a .node binary into build/Debug/ or build/Release/ depending on the build mode, and that file is what Node.js loads.

The header download is the part that surprises people. Depending on which Node.js is installed on the system, node-gyp downloads the development files or headers for the target version. That download is why a first build on a clean machine can fail on network access rather than on a compiler error, and it is also why the tool carries dependencies like tar and undici in package.json.

There is a documented branch for third-party runtimes. When building for Electron or another runtime with different build configuration, the README says to pass --dist-url or --nodedir to point at that runtime's headers. In that mode node-gyp reads the config.gypi shipped with the headers instead of the process.config object of the running Node.js. The README notes that some old Electron versions shipped malformed config.gypi files, and that --force-process-config exists to work around configuration errors from that.

Installing node-gyp and running a first build

The README states node-gyp is installed globally with npm. The Python constraint is worth reading before the command: Python v3.12 or later requires node-gyp v10 or later.

bash
npm install -g node-gyp

That installs only the tool. The README then lists what each operating system needs. On Unix you need a supported version of Python, make, and a C/C++ toolchain such as GCC. On macOS you need a supported Python plus the Xcode Command Line Tools, which the README says can be installed standalone with xcode-select --install. On Windows there is a Chocolatey path that installs Python and the Visual Studio C++ workload together.

bash
choco install python visualstudio2026-workload-vctools -y

Once the toolchain is in place, the build is three commands from the addon root. The README's example starts by entering the addon directory, then running configure, which looks for binding.gyp in the current directory.

bash
cd my_node_addon
node-gyp configure
node-gyp build

After configure you should see a Makefile or vcxproj under build/. After build you should see the compiled .node file in build/Debug/ or build/Release/. Passing --debug or -d to configure, build or rebuild produces a Debug build instead. On Windows, the README warns that auto-detection fails for Visual C++ Build Tools 2015, so --msvs_version=2015 must be added, though not when node-gyp is invoked through npm with the configuration described below.

Python selection is where most installations go wrong, and the README gives four mechanisms in priority order. The --python flag is per-command. The npm_config_python environment variable is the one to use when npm calls node-gyp, since npm passes it through.

bash
export npm_config_python=/path/to/executable/python

On Windows the README shows listing interpreters first and then setting the variable in CMD or PowerShell:

console
py --list-paths
set npm_config_python=C:\path\to\python.exe
$Env:npm_config_python="C:\path\to\python.exe"

The PYTHON environment variable is consulted third, and NODE_GYP_FORCE_PYTHON overrides everything else. The README is clear that if the forced interpreter is not a compatible version, no further searching happens, so an incorrect value fails the build outright rather than falling back.

Where node-gyp is the wrong tool

The dependency surface is the first limit. node-gyp needs Python, a C/C++ compiler and make or Visual Studio, on every machine that builds the addon, including CI runners and contributor laptops. For a project whose consumers only install prebuilt binaries, that requirement is pure overhead. Shipping prebuilds for each platform and Node.js ABI removes the compile step entirely, and node-gyp is then needed only on the machines that produce those binaries.

The second limit is the environment-variable precedence. Four ways to select Python, with NODE_GYP_FORCE_PYTHON silently disabling the search when it points at an incompatible version, is a configuration surface that fails without a clear recovery path. The README documents the order but does not document what a correct fallback looks like when the forced path is wrong.

Third, the README does not document rollback or an uninstall procedure for downloaded headers, and it does not describe how to clean a partially generated build/ directory. The configure and build commands are documented; recovery from a half-finished configure is not. If your build fails midway, the README's guidance stops at rerunning the commands.

Finally, the engines field in package.json requires Node.js ^22.22.2, ^24.15.0 or >=26.0.0. Older Node.js lines cannot run this version of the tool at all, which matters if you are pinned to an older runtime and expecting the current release to work.

node-gyp compared with prebuild and node-pre-gyp

The realistic alternative is not another build file generator. It is the prebuilt-binary approach, where the addon is compiled once per platform and published, and the install step downloads an artifact instead of invoking a compiler. The difference in approach is where the toolchain lives. With node-gyp the compiler must exist on the consumer's machine and the build happens at install time. With prebuilds the compiler exists only on the maintainer's release machine, and the consumer's install is a download.

That trade is not free in either direction. Prebuilds mean you must publish an artifact for every platform and Node.js ABI combination you support, and a missing combination falls back to a source build anyway. node-gyp means you support every combination with one binding.gyp, at the cost of requiring a working toolchain everywhere. Projects that ship both usually treat the source build as the fallback path and the prebuilt binary as the default.

The README does not name or compare against any prebuild tool, so treat this as a design distinction rather than a documented migration path. If you go the prebuild route, node-gyp remains the thing that produces the binaries you publish.

Maintenance cost, release cadence and licence

The repository is not archived, and the last push was on 2026-09-21. Releases are frequent: v13.0.0 on 2026-06-12, v13.0.1 on 2026-07-02 and v13.0.2 on 2026-08-26. That cadence is a cost as well as a signal. The package.json installVersion field is set to 11, which is the number node-gyp uses to decide whether a cached copy of its own headers is still current, so a major bump can invalidate cached headers on build machines and force a re-download.

The version constraint in engines is the upgrade cost most teams miss. Moving to this release means moving your build environment to Node.js ^22.22.2, ^24.15.0 or >=26.0.0. The README pairs that with the Python rule: Python v3.12 or later requires node-gyp v10 or later. Upgrade the two together or neither.

The licence is MIT, stated in both the README badge area and package.json. MIT is permissive and permits commercial and closed-source use, but the repository also vendors a copy of gyp-next under gyp/, so anyone auditing licence obligations should check the notices for that vendored tree rather than assuming the root LICENSE covers every file. That is a factual observation about the repository layout, not legal advice.

Editorial conclusion

Adopt node-gyp if you ship a native addon or maintain a package with C or C++ sources, and if you can pin a toolchain on every machine that builds it. Do not adopt it if you only consume prebuilt binaries or want a compiler-free install path, because it pulls in Python, make and a platform C++ compiler before it can produce anything. Before committing, verify three things on your own hardware: which Python node-gyp resolves when several are installed, whether npm_config_python is set in your CI environment, and whether the project's binding.gyp targets a Node.js version your engines field actually allows.

Frequently asked questions

What is node-gyp used for?

It compiles native addon modules for Node.js from C or C++ sources. The README describes it as a cross-platform command-line tool that reads a binding.gyp file and produces a .node binary in build/Debug/ or build/Release/. It is not used to build Node.js itself.

How do I install node-gyp?

Install it globally with npm install -g node-gyp, then install the platform prerequisites: a supported Python plus make and a C/C++ toolchain on Unix, the Xcode Command Line Tools on macOS, or the Visual Studio C++ workload on Windows. Python v3.12 or later requires node-gyp v10 or later.

How do I rebuild with node-gyp?

The README documents configure, build and rebuild as commands that accept the --debug or -d switch to produce a Debug build. Run them from the addon root, where the binding.gyp file lives. The compiled output lands in build/Debug/ or build/Release/.

What is a binding.gyp file?

It is the build description node-gyp reads. The README states that the configure step looks for a binding.gyp file in the current directory to process, and that file is what determines the generated Makefile or vcxproj.

Official sources

  1. Issues
  2. License: MIT
  3. nodejs/node-gyp on GitHub
  4. README
  5. Releases
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nodejs-node-gyp.svg)](https://hysenlabs.com/projects/nodejs-node-gyp)
Community notes

Community notes