Overview
Bundling Node.js applications with tools like esbuild or webpack requires special handling for dd-trace. The tracer uses dynamicrequire() calls and diagnostic channels to instrument third-party packages at runtime. Bundlers that inline all dependencies break this mechanism.
esbuild
Datadog provides an official esbuild plugin:packages/datadog-esbuild (published as part of the dd-trace package).
Install
The esbuild plugin is included withdd-trace. You only need esbuild itself:
npm
Configure the plugin
build.mjs
build.js
What the plugin does
Thedatadog-esbuild plugin:
- Intercepts the resolution of all modules that dd-trace instruments (Express, pg, Redis, etc.)
- Wraps each module file so that a
dd-trace:bundler:loaddiagnostic channel event is published when the module is loaded at runtime, allowing dd-trace to apply its instrumentation. - Adds a banner to the bundle that injects git metadata (
DD_GIT_REPOSITORY_URL,DD_GIT_COMMIT_SHA) from the build environment. - Handles ESM output (
.mjs/format: 'esm') by generating ESM-compatible interop wrappers.
Minification
IAST support
To enable IAST (Interactive Application Security Testing) with esbuild, setDD_IAST_ENABLED=true before running your build script. The plugin will automatically apply code rewriting to application files.
ESM bundle output
The plugin supports ESM output format. When building to ESM, it injects a banner that providesrequire, __filename, and __dirname globals needed by the instrumentation:
webpack
Datadog does not provide an official webpack plugin. The recommended approach is to markdd-trace as external so webpack does not bundle it:
webpack.config.js
dd-trace and all its instrumented packages in node_modules and requires them at runtime rather than bundling them.
Alternatively, mark all
node_modules as external using the webpack-node-externals package:webpack.config.js
General bundling caveats
Dynamic requires
Dynamic requires
dd-trace uses dynamic
require() calls to load instrumented packages lazily. Many bundlers replace these with static requires or remove them, which breaks instrumentation. Always use the esbuild plugin or mark dd-trace as external.Diagnostic channels
Diagnostic channels
The instrumentation system relies on Node.js diagnostic channels (
node:diagnostics_channel). This works correctly at runtime but requires that the instrumented packages are loaded through the same require function that dd-trace has patched. Bundled code that inlines dependencies breaks this.ESM interop
ESM interop
When building ESM output, modules that use
require() internally need CJS interop. The esbuild plugin handles this, but other bundlers may not.Source maps
Source maps
When
sourcemap is enabled in esbuild, the IAST code rewriter uses source maps to report accurate file locations. Pass sourcemap: true (or 'inline' or 'both') in your esbuild config when using IAST.