{"id":14983149,"url":"https://github.com/discordjs/node-pre-gyp","last_synced_at":"2025-10-03T04:30:45.724Z","repository":{"id":40705083,"uuid":"260551829","full_name":"discordjs/node-pre-gyp","owner":"discordjs","description":"Node.js tool for easy binary deployment of C++ addons","archived":false,"fork":true,"pushed_at":"2023-07-18T23:35:24.000Z","size":1302,"stargazers_count":4,"open_issues_count":3,"forks_count":3,"subscribers_count":3,"default_branch":"discordjs","last_synced_at":"2024-05-21T19:38:46.836Z","etag":null,"topics":["c","cpp","module","native","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"mapbox/node-pre-gyp","license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/discordjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-05-01T20:26:04.000Z","updated_at":"2024-01-31T00:42:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"d1d79ef3-49a7-4084-b078-297eca03ef2e","html_url":"https://github.com/discordjs/node-pre-gyp","commit_stats":{"total_commits":1076,"total_committers":72,"mean_commits":"14.944444444444445","dds":0.474907063197026,"last_synced_commit":"5012ad7fed9fb13e38591855d52f111833cd3f8c"},"previous_names":[],"tags_count":100,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/discordjs%2Fnode-pre-gyp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/discordjs%2Fnode-pre-gyp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/discordjs%2Fnode-pre-gyp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/discordjs%2Fnode-pre-gyp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/discordjs","download_url":"https://codeload.github.com/discordjs/node-pre-gyp/tar.gz/refs/heads/discordjs","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219867664,"owners_count":16554349,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","cpp","module","native","nodejs"],"created_at":"2024-09-24T14:06:48.578Z","updated_at":"2025-10-03T04:30:40.390Z","avatar_url":"https://github.com/discordjs.png","language":"JavaScript","readme":"# @discordjs/node-pre-gyp ![Test](https://github.com/discordjs/node-pre-gyp/workflows/Test/badge.svg)\n\n\u003e node-pre-gyp makes it easy to publish and install Node.js C++ addons from binaries\n\n`@discordjs/node-pre-gyp` stands between [npm](https://github.com/npm/npm) and [node-gyp](https://github.com/Tootallnate/node-gyp) and offers a cross-platform method of binary deployment.\n\n# Features\n\n- A command line tool called `node-pre-gyp` that can install your package's C++ module from a binary.\n- A variety of developer targeted commands for packaging, testing, and publishing binaries.\n- A JavaScript module that can dynamically require your installed binary: `require('@discordjs/node-pre-gyp').find`\n\nFor a hello world example of a module packaged with `node-pre-gyp` see \u003chttps://github.com/springmeyer/node-addon-example\u003e and [the wiki ](https://github.com/mapbox/node-pre-gyp/wiki/Modules-using-node-pre-gyp) for real world examples.\n\n# Credits\n\n- The module is modeled after [node-gyp](https://github.com/Tootallnate/node-gyp) by [@Tootallnate](https://github.com/Tootallnate)\n- Motivation for initial development came from [@ErisDS](https://github.com/ErisDS) and the [Ghost Project](https://github.com/TryGhost/Ghost).\n- Development is sponsored by [Mapbox](https://www.mapbox.com/)\n\n# FAQ\n\nSee the [Frequently Ask Questions](https://github.com/mapbox/node-pre-gyp/wiki/FAQ).\n\n# Usage\n\n## Commands\n\nView all possible commands:\n\n    node-pre-gyp --help\n\n- clean - Remove the entire folder containing the compiled .node module\n- install - Install pre-built binary for module\n- reinstall - Run \"clean\" and \"install\" at once\n- build - Compile the module by dispatching to node-gyp or nw-gyp\n- rebuild - Run \"clean\" and \"build\" at once\n- package - Pack binary into tarball\n- testpackage - Test that the staged package is valid\n\nYou can also chain commands:\n\n```bash\nnode-pre-gyp clean build package\n```\n\n## Options\n\nOptions include:\n\n- `-C/--directory`: run the command in this directory\n- `--build-from-source`: build from source instead of using pre-built binary\n- `--update-binary`: reinstall by replacing previously installed local binary with remote binary\n- `--runtime=electron`: customize the runtime: `node` and `electron` are the valid options\n- `--fallback-to-build`: fallback to building from source if pre-built binary is not available\n- `--target=0.4.0`: Pass the target node or node-webkit version to compile against\n- `--target_arch=ia32`: Pass the target arch and override the host `arch`. Any value that is [supported by Node.js](https://nodejs.org/api/os.html#osarch) is valid.\n- `--target_platform=win32`: Pass the target platform and override the host `platform`. Valid values are `linux`, `darwin`, `win32`, `sunos`, `freebsd`, `openbsd`, and `aix`.\n\nBoth `--build-from-source` and `--fallback-to-build` can be passed alone or they can provide values. You can pass `--fallback-to-build=false` to override the option as declared in package.json. In addition to being able to pass `--build-from-source` you can also pass `--build-from-source=myapp` where `myapp` is the name of your module.\n\nFor example: `npm install --build-from-source=myapp`. This is useful if:\n\n- `myapp` is referenced in the package.json of a larger app and therefore `myapp` is being installed as a dependency with `npm install`.\n- The larger app also depends on other modules installed with `node-pre-gyp`\n- You only want to trigger a source compile for `myapp` and the other modules.\n\n# Configuring\n\nThis is a guide to configuring your module to use node-pre-gyp.\n\n## 1) Add new entries to your `package.json`\n\n- Add `node-pre-gyp` to `dependencies`\n- Add a custom `install` script\n- Declare a `binary` object\n\nThis looks like:\n\n```json\n\"dependencies\"  : {\n  \"@discordjs/node-pre-gyp\": \"0.1.x\"\n},\n\"scripts\": {\n  \"install\": \"node-pre-gyp install --fallback-to-build\"\n},\n\"binary\": {\n  \"module_name\": \"your_module\",\n  \"module_path\": \"./lib/binding/\",\n  \"host\": \"https://your_module.s3-us-west-1.amazonaws.com\"\n}\n```\n\nFor a full example see [node-addon-examples's package.json](https://github.com/springmeyer/node-addon-example/blob/master/package.json).\n\nLet's break this down:\n\n- Dependencies need to list `node-pre-gyp`\n- Your `scripts` section should override the `install` target with `\"install\": \"node-pre-gyp install --fallback-to-build\"`. This allows node-pre-gyp to be used instead of the default npm behavior of always source compiling with `node-gyp` directly.\n- Your package.json should contain a `binary` section describing key properties you provide to allow node-pre-gyp to package optimally. They are detailed below.\n\n### The `binary` object has three required properties\n\n### module_name\n\nThe name of your native node module. This value must:\n\n- Match the name passed to [the NODE_MODULE macro](http://nodejs.org/api/addons.html#addons_hello_world)\n- Must be a valid C variable name (e.g. it cannot contain `-`)\n- Should not include the `.node` extension.\n\n### module_path\n\nThe location your native module is placed after a build. This should be an empty directory without other Javascript files. This entire directory will be packaged in the binary tarball. When installing from a remote package this directory will be overwritten with the contents of the tarball.\n\nNote: This property supports variables based on [Versioning](#versioning).\n\n### host\n\nA url to the remote location where you've published tarball binaries (must be `https` not `http`).\n\n### remote_path\n\nIt **is recommended** that you customize this property. This is an extra path to use for publishing and finding remote tarballs. The default value for `remote_path` is `\"\"` meaning that if you do not provide it then all packages will be published at the base of the `host`. It is recommended to provide a value like `./{name}/v{version}` to help organize remote packages in the case that you choose to publish multiple node addons to the same `host`.\n\nNote: This property supports variables based on [Versioning](#versioning).\n\n### package_name\n\nIt is **not recommended** to override this property unless you are also overriding the `remote_path`. This is the versioned name of the remote tarball containing the binary `.node` module and any supporting files you've placed inside the `module_path` directory. Unless you specify `package_name` in your `package.json` then it defaults to `{module_name}-v{version}-{node_abi}-{platform}-{arch}.tar.gz` which allows your binary to work across node versions, platforms, and architectures. If you are using `remote_path` that is also versioned by `./{module_name}/v{version}` then you could remove these variables from the `package_name` and just use: `{node_abi}-{platform}-{arch}.tar.gz`. Then your remote tarball will be looked up at, for example, `https://example.com/your-module/v0.1.0/node-v11-linux-x64.tar.gz`.\n\nAvoiding the version of your module in the `package_name` and instead only embedding in a directory name can be useful when you want to make a quick tag of your module that does not change any C++ code.\n\nNote: This property supports variables based on [Versioning](#versioning).\n\n## 2) Add a new target to binding.gyp\n\n`node-pre-gyp` calls out to `node-gyp` to compile the module and passes variables along like [module_name](#module_name) and [module_path](#module_path).\n\nA new target must be added to `binding.gyp` that moves the compiled `.node` module from `./build/Release/module_name.node` into the directory specified by `module_path`.\n\nAdd a target like this at the end of your `targets` list:\n\n```json\n{\n\t\"target_name\": \"action_after_build\",\n\t\"type\": \"none\",\n\t\"dependencies\": [\"\u003c(module_name)\"],\n\t\"copies\": [\n\t\t{\n\t\t\t\"files\": [\"\u003c(PRODUCT_DIR)/\u003c(module_name).node\"],\n\t\t\t\"destination\": \"\u003c(module_path)\"\n\t\t}\n\t]\n}\n```\n\nFor a full example see [node-addon-example's binding.gyp](https://github.com/springmeyer/node-addon-example/blob/2ff60a8ded7f042864ad21db00c3a5a06cf47075/binding.gyp).\n\n## 3) Dynamically require your `.node`\n\nInside the main js file that requires your addon module you are likely currently doing:\n\n```js\nconst binding = require('../build/Release/binding.node');\n```\n\nor:\n\n```js\nconst bindings = require('./bindings');\n```\n\nChange those lines to:\n\n```js\nconst binary = require('@discordjs/node-pre-gyp');\nconst path = require('path');\nconst binding_path = binary.find(path.resolve(path.join(__dirname, './package.json')));\nconst binding = require(binding_path);\n```\n\nFor a full example see [node-addon-example's index.js](https://github.com/springmeyer/node-addon-example/blob/2ff60a8ded7f042864ad21db00c3a5a06cf47075/index.js#L1-L4)\n\n## 4) Build and package your app\n\nNow build your module from source:\n\n```bash\nnpm install --build-from-source\n```\n\nThe `--build-from-source` tells `node-pre-gyp` to not look for a remote package and instead dispatch to node-gyp to build.\n\nNow `node-pre-gyp` should now also be installed as a local dependency so the command line tool it offers can be found at `./node_modules/.bin/node-pre-gyp`.\n\n## 5) Test\n\nNow `npm test` should work just as it did before.\n\n## 6) Publish the tarball\n\nThen package your app:\n\n    ./node_modules/.bin/node-pre-gyp package\n\nOnce packaged you can also host your binaries. To do this requires:\n\n- You manually publish the binary created by the `package` command to an `https` endpoint\n- Ensure that the `host` value points to your custom `https` endpoint.\n\n## 7) You're done!\n\nNow publish your module to the npm registry. Users will now be able to install your module from a binary.\n\nWhat will happen is this:\n\n1. `npm install \u003cyour package\u003e` will pull from the npm registry\n2. npm will run the `install` script which will call out to `node-pre-gyp`\n3. `node-pre-gyp` will fetch the binary `.node` module and unpack in the right place\n4. Assuming that all worked, you are done\n\nIf a a binary was not available for a given platform and `--fallback-to-build` was used then `node-gyp rebuild` will be called to try to source compile the module.\n\n## N-API Considerations\n\n[Node-API](https://nodejs.org/api/n-api.html#n_api_node_api), which was previously known as N-API, is an ABI-stable alternative to previous technologies such as [nan](https://github.com/nodejs/nan) which are tied to a specific Node runtime engine. Node-API is Node runtime engine agnostic and guarantees modules created today will continue to run, without changes, into the future.\n\nUsing `node-pre-gyp` with Node-API projects requires a handful of additional configuration values and imposes some additional requirements.\n\nThe most significant difference is that an Node-API module can be coded to target multiple Node-API versions. Therefore, an Node-API module must declare in its `package.json` file which Node-API versions the module is designed to run against. In addition, since multiple builds may be required for a single module, path and file names must be specified in way that avoids naming conflicts.\n\n## The `napi_versions` array property\n\nA Node-API module must declare in its `package.json` file, the Node-API versions the module is intended to support. This is accomplished by including an `napi-versions` array property in the `binary` object. For example:\n\n```json\n\"binary\": {\n  \"module_name\": \"your_module\",\n  \"module_path\": \"your_module_path\",\n  \"host\": \"https://your_bucket.s3-us-west-1.amazonaws.com\",\n  \"napi_versions\": [1,3]\n}\n```\n\nIf the `napi_versions` array property is _not_ present, `node-pre-gyp` operates as it always has. Including the `napi_versions` array property instructs `node-pre-gyp` that this is a Node-API module build.\n\nWhen the `napi_versions` array property is present, `node-pre-gyp` fires off multiple operations, one for each of the Node-API versions in the array. In the example above, two operations are initiated, one for Node-API version 1 and second for Node-API version 3. How this version number is communicated is described next.\n\n## The `napi_build_version` value\n\nFor each of the Node-API module operations `node-pre-gyp` initiates, it ensures that the `napi_build_version` is set appropriately.\n\nThis value is of importance in two areas:\n\n1. The C/C++ code which needs to know against which Node-API version it should compile.\n2. `node-pre-gyp` itself which must assign appropriate path and file names to avoid collisions.\n\n## Defining `NAPI_VERSION` for the C/C++ code\n\nThe `napi_build_version` value is communicated to the C/C++ code by adding this code to the `binding.gyp` file:\n\n```json\n\"defines\": [\n    \"NAPI_VERSION=\u003c(napi_build_version)\",\n]\n```\n\nThis ensures that `NAPI_VERSION`, an integer value, is declared appropriately to the C/C++ code for each build.\n\n\u003e Note that earlier versions of this document recommended defining the symbol `NAPI_BUILD_VERSION`. `NAPI_VERSION` is preferred because it used by the Node-API C/C++ headers to configure the specific Node-API versions being requested.\n\n## Path and file naming requirements in `package.json`\n\nSince `node-pre-gyp` fires off multiple operations for each request, it is essential that path and file names be created in such a way as to avoid collisions. This is accomplished by imposing additional path and file naming requirements.\n\nSpecifically, when performing Node-API builds, the `{napi_build_version}` text configuration value _must_ be present in the `module_path` property. In addition, the `{napi_build_version}` text configuration value _must_ be present in either the `remote_path` or `package_name` property. (No problem if it's in both.)\n\nHere's an example:\n\n```json\n\"binary\": {\n  \"module_name\": \"your_module\",\n  \"module_path\": \"./lib/binding/napi-v{napi_build_version}\",\n  \"remote_path\": \"./{module_name}/v{version}/{configuration}/\",\n  \"package_name\": \"{platform}-{arch}-napi-v{napi_build_version}.tar.gz\",\n  \"host\": \"https://your_bucket.s3-us-west-1.amazonaws.com\",\n  \"napi_versions\": [1,3]\n}\n```\n\n## Supporting both N-API and NAN builds\n\nYou may have a legacy native add-on that you wish to continue supporting for those versions of Node that do not support Node-API, as you add Node-API support for later Node versions. This can be accomplished by specifying the `node_napi_label` configuration value in the package.json `binary.package_name` property.\n\nPlacing the configuration value `node_napi_label` in the package.json `binary.package_name` property instructs `node-pre-gyp` to build all viable Node-API binaries supported by the current Node instance. If the current Node instance does not support Node-API, `node-pre-gyp` will request a traditional, non-Node-API build.\n\nThe configuration value `node_napi_label` is set by `node-pre-gyp` to the type of build created, `napi` or `node`, and the version number. For Node-API builds, the string contains the Node-API version nad has values like `napi-v3`. For traditional, non-Node-API builds, the string contains the ABI version with values like `node-v46`.\n\nHere's how the `binary` configuration above might be changed to support both Node-API and NAN builds:\n\n```json\n\"binary\": {\n  \"module_name\": \"your_module\",\n  \"module_path\": \"./lib/binding/{node_napi_label}\",\n  \"remote_path\": \"./{module_name}/v{version}/{configuration}/\",\n  \"package_name\": \"{platform}-{arch}-{node_napi_label}.tar.gz\",\n  \"host\": \"https://your_bucket.s3-us-west-1.amazonaws.com\",\n  \"napi_versions\": [1,3]\n}\n```\n\nThe C/C++ symbol `NAPI_VERSION` can be used to distinguish Node-API and non-Node-API builds. The value of `NAPI_VERSION` is set to the integer Node-API version for Node-API builds and is set to `0` for non-Node-API builds.\n\nFor example:\n\n```C\n#if NAPI_VERSION\n// Node-API code goes here\n#else\n// NAN code goes here\n#endif\n```\n\n## Two additional configuration values\n\nThe following two configuration values, which were implemented in previous versions of `node-pre-gyp`, continue to exist, but have been replaced by the `node_napi_label` configuration value described above.\n\n1. `napi_version` If Node-API is supported by the currently executing Node instance, this value is the Node-API version number supported by Node. If Node-API is not supported, this value is an empty string.\n\n2. `node_abi_napi` If the value returned for `napi_version` is non empty, this value is `'napi'`. If the value returned for `napi_version` is empty, this value is the value returned for `node_abi`.\n\nThese values are present for use in the `binding.gyp` file and may be used as `{napi_version}` and `{node_abi_napi}` for text substituion in the `binary` properties of the `package.json` file.\n\n# Versioning\n\nThe `binary` properties of `module_path`, `remote_path`, and `package_name` support variable substitution. The strings are evaluated by `node-pre-gyp` depending on your system and any custom build flags you passed.\n\n- `node_abi`: The node C++ `ABI` number. This value is available in Javascript as `process.versions.modules` as of [`\u003e= v0.10.4 \u003e= v0.11.7`](https://github.com/joyent/node/commit/ccabd4a6fa8a6eb79d29bc3bbe9fe2b6531c2d8e) and in C++ as the `NODE_MODULE_VERSION` define much earlier. For versions of Node before this was available we fallback to the V8 major and minor version.\n- `platform` matches node's `process.platform` like `linux`, `darwin`, and `win32` unless the user passed the `--target_platform` option to override.\n- `arch` matches node's `process.arch` like `x64` or `ia32` unless the user passes the `--target_arch` option to override.\n- `libc` matches `require('detect-libc').family` like `glibc` or `musl` unless the user passes the `--target_libc` option to override.\n- `libc_version` matches `require('detect-libc').version`\n- `configuration` - Either 'Release' or 'Debug' depending on if `--debug` is passed during the build.\n- `module_name` - the `binary.module_name` attribute from `package.json`.\n- `version` - the semver `version` value for your module from `package.json` (NOTE: ignores the `semver.build` property).\n- `major`, `minor`, `patch`, and `prelease` match the individual semver values for your module's `version`\n- `build` - the sevmer `build` value. For example it would be `this.that` if your package.json `version` was `v1.0.0+this.that`\n- `prerelease` - the semver `prerelease` value. For example it would be `alpha.beta` if your package.json `version` was `v1.0.0-alpha.beta`\n\nThe options are visible in the code at \u003chttps://github.com/mapbox/node-pre-gyp/blob/612b7bca2604508d881e1187614870ba19a7f0c5/lib/util/versioning.js#L114-L127\u003e\n\n# Download binary files from a mirror\n\nS3 is broken in China for the well known reason.\n\nUsing the `npm` config argument: `--{module_name}_binary_host_mirror` can download binary files through a mirror, `-` in `module_name` will be replaced with `_`.\n\ne.g.: Install [v8-profiler](https://www.npmjs.com/package/v8-profiler) from `npm`.\n\n```bash\n$ npm install v8-profiler --profiler_binary_host_mirror=https://npm.taobao.org/mirrors/node-inspector/\n```\n\ne.g.: Install [canvas-prebuilt](https://www.npmjs.com/package/canvas-prebuilt) from `npm`.\n\n```bash\n$ npm install canvas-prebuilt --canvas_prebuilt_binary_host_mirror=https://npm.taobao.org/mirrors/canvas-prebuilt/\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiscordjs%2Fnode-pre-gyp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiscordjs%2Fnode-pre-gyp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiscordjs%2Fnode-pre-gyp/lists"}