Skip to main content

Runtime Module Hooks

envtrap injects a runtime hook script (hooks.mjs) into the application process via NODE_OPTIONS="--import hooks.mjs". This script executes before any user code or dependencies are loaded, establishing hooks for both ECMAScript Modules (ESM) and CommonJS (CJS).

1. ES Modules (module.register)

Node.js 18+ provides module customization hooks that intercept module resolution and loading:
When application code or an npm package imports node:child_process or node:dns, the resolve() hook intercepts the specifier and redirects it to an internal virtual URL protocol:
When Node.js attempts to load an envtrap:* URL, the load() hook serves our specialized virtual wrapper module (src/hooks/virtual/child-process.mjs or src/hooks/virtual/dns.mjs) directly from memory:

2. CommonJS (Module.prototype.require)

Because older packages still use CommonJS require(), hooks.mjs patches Module.prototype.require in the main application thread:
This guarantees that both ESM import statements and CommonJS require() calls receive identical security enforcement.

3. Call-Stack Path Exclusions

Before triggering an alert or throwing an error, virtual hooks inspect the execution call stack:
  1. An Error object is instantiated to capture the active call stack.
  2. The calling file path is evaluated against glob patterns configured in exclusions.paths.
  3. If the calling file is excluded (such as test suites or database seeders), the operation is permitted without raising an alert.