|
| 1 | +# Maintaining Dependencies |
| 2 | + |
| 3 | +Node.js depends on additional components beyond the Node.js code |
| 4 | +itself. These dependencies provide both native and JavaScript code |
| 5 | +and are built together with the code under the `src` and `lib` |
| 6 | +directories to create the Node.js binaries. |
| 7 | + |
| 8 | +All dependencies are located within the `deps` directory. |
| 9 | +This a list of all the dependencies: |
| 10 | + |
| 11 | +* [acorn][] |
| 12 | +* [ada][] |
| 13 | +* [base64][] |
| 14 | +* [brotli][] |
| 15 | +* [c-ares][] |
| 16 | +* [cjs-module-lexer][] |
| 17 | +* [corepack][] |
| 18 | +* [googletest][] |
| 19 | +* [histogram][] |
| 20 | +* [icu-small][] |
| 21 | +* [llhttp][] |
| 22 | +* [minimatch][] |
| 23 | +* [nghttp2][] |
| 24 | +* [ngtcp2][] |
| 25 | +* [npm][] |
| 26 | +* [openssl][] |
| 27 | +* [postject][] |
| 28 | +* [simdutf][] |
| 29 | +* [undici][] |
| 30 | +* [uv][] |
| 31 | +* [uvwasi][] |
| 32 | +* [V8][] |
| 33 | +* [zlib][] |
| 34 | + |
| 35 | +Any code which meets one or more of these conditions should |
| 36 | +be managed as a dependency: |
| 37 | + |
| 38 | +* originates in an upstream project and is maintained |
| 39 | + in that upstream project. |
| 40 | +* is not built from the `preferred form of the work for |
| 41 | + making modifications to it` (see |
| 42 | + [GNU GPL v2, section 3.](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) |
| 43 | + when `make node` is run. A good example is |
| 44 | + WASM code generated from C (the preferred form). |
| 45 | + Typically generation is only supported on a subset of platforms, needs |
| 46 | + additional tools, and is pre-built outside of the `make node` |
| 47 | + step and then committed as a WASM binary in the directory |
| 48 | + for the dependency under the `deps` directory. |
| 49 | + |
| 50 | +By default all dependencies are bundled into the Node.js |
| 51 | +binary, however, `configure` options should be available to |
| 52 | +use an externalized version at runtime when: |
| 53 | + |
| 54 | +* the dependency provides native code and is available as |
| 55 | + a shared library in one or more of the common Node.js |
| 56 | + distributions. |
| 57 | +* the dependency provides JavaScript and is not built |
| 58 | + from the `preferred form of the work for making modifications |
| 59 | + to it` when `make node` is run. |
| 60 | + |
| 61 | +Many distributions use externalized dependencies for one or |
| 62 | +more of these reasons: |
| 63 | + |
| 64 | +1. They have a requirement to build everything that they ship |
| 65 | + from the `preferred form of the work for making |
| 66 | + modifications to it`. This means that they need to |
| 67 | + replace any pre-built components (for example WASM |
| 68 | + binaries) with an equivalent that they have built. |
| 69 | +2. They manage the dependency separately as it is used by |
| 70 | + more applications than just Node.js. Linking against |
| 71 | + a shared library allows them to manage updates and |
| 72 | + CVE fixes against the library instead of having to |
| 73 | + patch all of the individual applications. |
| 74 | +3. They have a system wide configuration for the |
| 75 | + dependency that all applications should respect. |
| 76 | + |
| 77 | +## Supporting externalized dependencies with native code |
| 78 | + |
| 79 | +Support for externalized dependencies with native code for which a |
| 80 | +shared library is available can added by: |
| 81 | + |
| 82 | +* adding options to `configure.py`. These are added to the |
| 83 | + shared\_optgroup and include an options to: |
| 84 | + * enable use of a shared library |
| 85 | + * set the name of the shared library |
| 86 | + * set the path to the directory with the includes for the |
| 87 | + shared library |
| 88 | + * set the path to where to find the shared library at |
| 89 | + runtime |
| 90 | +* add a call to configure\_library() to `configure.py` for the |
| 91 | + library at the end of list of existing configure\_library() calls. |
| 92 | + If there are additional libraries that are required it is |
| 93 | + possible to list more than one with the `pkgname` option. |
| 94 | +* in `node.gypi` guard the build for the dependency |
| 95 | + with `node_shared_depname` so that it is only built if |
| 96 | + the dependency is being bundled into Node.js itself. For example: |
| 97 | + |
| 98 | +```text |
| 99 | + [ 'node_shared_brotli=="false"', { |
| 100 | + 'dependencies': [ 'deps/brotli/brotli.gyp:brotli' ], |
| 101 | + }], |
| 102 | +``` |
| 103 | + |
| 104 | +## Supporting externalizable dependencies with JavaScript code |
| 105 | + |
| 106 | +Support for an externalizable dependency with JavaScript code |
| 107 | +can be added by: |
| 108 | + |
| 109 | +* adding an entry to the `sharable_builtins` map in |
| 110 | + `configure.py`. The path should correspond to the file |
| 111 | + within the deps directory that is normally bundled into |
| 112 | + Node.js. For example `deps/cjs-module-lexer/lexer.js`. |
| 113 | + This will add a new option for building with that dependency |
| 114 | + externalized. After adding the entry you can see |
| 115 | + the new option by running `./configure --help`. |
| 116 | + |
| 117 | +* adding a call to `AddExternalizedBuiltin` to the constructor |
| 118 | + for BuiltinLoader in `src/node_builtins.cc` for the |
| 119 | + dependency using the `NODE_SHARED_BUILTLIN` #define generated for |
| 120 | + the dependency. After running `./configure` with the new |
| 121 | + option you can find the #define in `config.gypi`. You can cut and |
| 122 | + paste one of the existing entries and then update to match the |
| 123 | + import name for the dependency and the #define generated. |
| 124 | + |
| 125 | +## Supporting non-externalized dependencies with JavaScript code |
| 126 | + |
| 127 | +If the dependency consists of JavaScript in the |
| 128 | +`preferred form of the work for making modifications to it`, it |
| 129 | +can be added as a non-externalizable dependency. In this case |
| 130 | +simply add the path to the JavaScript file in the `deps_files` |
| 131 | +list in the `node.gyp` file. |
| 132 | + |
| 133 | +## Updating dependencies |
| 134 | + |
| 135 | +Most dependencies are automatically updated by |
| 136 | +[dependency-update-action][] that runs weekly. |
| 137 | +However, it is possible to manually update a dependency by running |
| 138 | +the corresponding script in `tools/update-deps`. |
| 139 | +[OpenSSL][] has its own update action: [update-openssl-action][]. |
| 140 | +[npm-cli-bot](https://github.com/npm/cli/blob/latest/.github/workflows/create-node-pr.yml) |
| 141 | +takes care of [npm][] update, it is maintained by the npm team. |
| 142 | + |
| 143 | +## Dependency list |
| 144 | + |
| 145 | +### acorn |
| 146 | + |
| 147 | +The [acorn](https://github.com/acornjs/acorn) dependency is a JavaScript parser. |
| 148 | +[acorn-walk](https://github.com/acornjs/acorn/tree/master/acorn-walk) is |
| 149 | +an abstract syntax tree walker for the ESTree format. |
| 150 | + |
| 151 | +### ada |
| 152 | + |
| 153 | +The [ada](https://github.com/ada-url/ada) dependency is a |
| 154 | +fast and spec-compliant URL parser written in C++. |
| 155 | + |
| 156 | +### base64 |
| 157 | + |
| 158 | +The [base64](https://github.com/aklomp/base64) dependency is a base64 |
| 159 | +stream encoding/decoding library in C99 with SIMD and OpenMP acceleration. |
| 160 | +It also contains wrapper functions to encode/decode simple |
| 161 | +length-delimited strings. |
| 162 | + |
| 163 | +### brotli |
| 164 | + |
| 165 | +The [brotli](https://github.com/google/brotli) dependency is |
| 166 | +used for the homonym generic-purpose lossless compression algorithm. |
| 167 | + |
| 168 | +### c-ares |
| 169 | + |
| 170 | +The [c-ares](https://github.com/c-ares/c-ares) is a C library |
| 171 | +for asynchronous DNS requests. |
| 172 | + |
| 173 | +### cjs-module-lexer |
| 174 | + |
| 175 | +The [cjs-module-lexer](https://github.com/nodejs/node/tree/HEAD/deps/cjs-module-lexer) |
| 176 | +dependency is used within the Node.js ESM implementation to detect the |
| 177 | +named exports of a CommonJS module. |
| 178 | +See [maintaining-cjs-module-lexer][] for more information. |
| 179 | + |
| 180 | +## corepack |
| 181 | + |
| 182 | +The [corepack](https://github.com/nodejs/corepack) dependency is a |
| 183 | +zero-runtime-dependency Node.js script that acts as a bridge between |
| 184 | +Node.js projects and the package managers they are intended to |
| 185 | +be used with during development. |
| 186 | +In practical terms, Corepack will let you use Yarn and pnpm without having to |
| 187 | +install them - just like what currently happens with npm, which is shipped |
| 188 | +by Node.js by default. |
| 189 | + |
| 190 | +### googletest |
| 191 | + |
| 192 | +The [googletest](https://github.com/google/googletest) dependency is Google’s |
| 193 | +C++ testing and mocking framework. |
| 194 | + |
| 195 | +### histogram |
| 196 | + |
| 197 | +The [histogram](https://github.com/HdrHistogram/HdrHistogram_c) dependency is |
| 198 | +a C port of High Dynamic Range (HDR) Histogram. |
| 199 | + |
| 200 | +### icu-small |
| 201 | + |
| 202 | +The [icu](http://site.icu-project.org) is widely used set of C/C++ |
| 203 | +and Java libraries providing Unicode and Globalization |
| 204 | +support for software applications. |
| 205 | +See [maintaining-icu][] for more informations. |
| 206 | + |
| 207 | +### llhttp |
| 208 | + |
| 209 | +The [llhttp](https://github.com/nodejs/llhttp) dependency is |
| 210 | +the http parser used by Node.js. |
| 211 | +See [maintaining-http][] for more informations. |
| 212 | + |
| 213 | +### minimatch |
| 214 | + |
| 215 | +The [minimatch](https://github.com/isaacs/minimatch) dependency is a |
| 216 | +minimal matching utility. |
| 217 | + |
| 218 | +### nghttp2 |
| 219 | + |
| 220 | +The [nghttp2](https://github.com/nghttp2/nghttp2) dependency is a C library |
| 221 | +implementing HTTP/2 protocol. |
| 222 | +See [maintaining-http][] for more informations. |
| 223 | + |
| 224 | +### ngtcp2 |
| 225 | + |
| 226 | +The ngtcp2 and nghttp3 dependencies provide the core functionality for |
| 227 | +QUIC and HTTP/3. |
| 228 | + |
| 229 | +The sources are pulled from: |
| 230 | + |
| 231 | +* ngtcp2: <https://github.com/ngtcp2/ngtcp2> |
| 232 | +* nghttp3: <https://github.com/ngtcp2/nghttp3> |
| 233 | + |
| 234 | +In both the `ngtcp2` and `nghttp3` git repos, the active development occurs |
| 235 | +in the default branch (currently named `main` in each). Tagged versions do not |
| 236 | +always point to the default branch. |
| 237 | + |
| 238 | +We only use a subset of the sources for each. |
| 239 | + |
| 240 | +The `nghttp3` library depends on `ngtcp2`. Both should always be updated |
| 241 | +together. From `ngtcp2` we only want the contents of the `lib` and `crypto` |
| 242 | +directories; from `nghttp3` we only want the contents of the `lib` directory. |
| 243 | + |
| 244 | +### npm |
| 245 | + |
| 246 | +The [npm](https://github.com/npm/cli) dependency is |
| 247 | +the package manager for JavaScript. |
| 248 | + |
| 249 | +New pull requests should be opened when a "next" version of npm has |
| 250 | +been released. Once the "next" version has been promoted to "latest" |
| 251 | +the PR should be updated as necessary. |
| 252 | + |
| 253 | +The specific Node.js release streams the new version will be able to land into |
| 254 | +are at the discretion of the release and LTS teams. |
| 255 | + |
| 256 | +This process only covers full updates to new versions of npm. Cherry-picked |
| 257 | +changes can be reviewed and landed via the normal consensus seeking process. |
| 258 | + |
| 259 | +### openssl |
| 260 | + |
| 261 | +The [openssl](https://github.com/quictls/openssl) dependency is a |
| 262 | +fork of OpenSSL to enable QUIC. |
| 263 | +[OpenSSL](https://www.openssl.org/) is toolkit for general-purpose |
| 264 | +cryptography and secure communication. |
| 265 | + |
| 266 | +Node.js currently uses the quictls/openssl fork, which closely tracks |
| 267 | +the main openssl/openssl releases with the addition of APIs to support |
| 268 | +the QUIC protocol. |
| 269 | +See [maintaining-openssl][] for more informations. |
| 270 | + |
| 271 | +### postject |
| 272 | + |
| 273 | +The [postject](https://github.com/nodejs/postject) dependency is used for the |
| 274 | +[Single Executable strategic initiative](https://github.com/nodejs/single-executable). |
| 275 | + |
| 276 | +### simdutf |
| 277 | + |
| 278 | +The [simdutf](https://github.com/simdutf/simdutf) dependency is |
| 279 | +a C++ library for fast UTF-8 decoding and encoding. |
| 280 | + |
| 281 | +### undici |
| 282 | + |
| 283 | +The [undici](https://github.com/nodejs/undici) dependency is an HTTP/1.1 client, |
| 284 | +written from scratch for Node.js.. |
| 285 | +See [maintaining-http][] for more informations. |
| 286 | + |
| 287 | +### uv |
| 288 | + |
| 289 | +The [libuv](https://github.com/libuv/libuv) dependency is a |
| 290 | +multi-platform support library with a focus on asynchronous I/O. |
| 291 | +It was primarily developed for use by Node.js. |
| 292 | + |
| 293 | +### uvwasi |
| 294 | + |
| 295 | +The [uvwasi](https://github.com/nodejs/uvwasi) dependency implements |
| 296 | +the WASI system call API, so that WebAssembly runtimes can easily |
| 297 | +implement WASI calls. |
| 298 | +Under the hood, uvwasi leverages libuv where possible for maximum portability. |
| 299 | +See [maintaining-web-assembly][] for more informations. |
| 300 | + |
| 301 | +### V8 |
| 302 | + |
| 303 | +[V8](https://chromium.googlesource.com/v8/v8.git/) is Google's open source |
| 304 | +high-performance JavaScript and WebAssembly engine, written in C++. |
| 305 | +See [maintaining-V8][] for more informations. |
| 306 | + |
| 307 | +### zlib |
| 308 | + |
| 309 | +The [zlib](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/zlib) |
| 310 | +dependency lossless data-compression library, |
| 311 | +it comes from the Chromium team's zlib fork which incorporated |
| 312 | +performance improvements not currently available in standard zlib. |
| 313 | + |
| 314 | +[acorn]: #acorn |
| 315 | +[ada]: #ada |
| 316 | +[base64]: #base64 |
| 317 | +[brotli]: #brotli |
| 318 | +[c-ares]: #c-ares |
| 319 | +[cjs-module-lexer]: #cjs-module-lexer |
| 320 | +[corepack]: #corepack |
| 321 | +[dependency-update-action]: ../../../.github/workflows/tools.yml |
| 322 | +[googletest]: #googletest |
| 323 | +[histogram]: #histogram |
| 324 | +[icu-small]: #icu-small |
| 325 | +[llhttp]: #llhttp |
| 326 | +[maintaining-V8]: ./maintaining-V8.md |
| 327 | +[maintaining-cjs-module-lexer]: ./maintaining-cjs-module-lexer.md |
| 328 | +[maintaining-http]: ./maintaining-http.md |
| 329 | +[maintaining-icu]: ./maintaining-icu.md |
| 330 | +[maintaining-openssl]: ./maintaining-openssl.md |
| 331 | +[maintaining-web-assembly]: ./maintaining-web-assembly.md |
| 332 | +[minimatch]: #minimatch |
| 333 | +[nghttp2]: #nghttp2 |
| 334 | +[ngtcp2]: #ngtcp2 |
| 335 | +[npm]: #npm |
| 336 | +[openssl]: #openssl |
| 337 | +[postject]: #postject |
| 338 | +[simdutf]: #simdutf |
| 339 | +[undici]: #undici |
| 340 | +[update-openssl-action]: ../../../.github/workflows/update-openssl.yml |
| 341 | +[uv]: #uv |
| 342 | +[uvwasi]: #uvwasi |
| 343 | +[v8]: #v8 |
| 344 | +[zlib]: #zlib |
0 commit comments