Often not well. Wrangler uses esbuild to combine your code and npm modules into one entry file, so package names and versions can disappear from view. Scan the lockfile before the build and compare it with a dry run bundle, so you know which packages made it into the deployed Worker.
What bundling does
The Cloudflare documentation says Wrangler bundles Worker code with esbuild by default, and supports importing npm modules listed in package.json. Bundling takes multiple modules and combines them into one file, so dependencies end up inside the entry point file unless you configure otherwise.
Two details matter for security work. Wrangler respects the conditional exports field in package.json and tries to load the workerd key, which means the file that ships may differ from the one a default Node install would use. And non JavaScript files such as .wasm are uploaded as separate modules by default.
Why this hides things from scanners
| Scan target | What it sees | What it can miss |
|---|---|---|
| package.json and lockfile | Declared and resolved packages with versions | Whether tree shaking dropped code, and which export condition was used |
| node_modules folder | Everything installed | Dev only packages that never ship |
| Final bundle | The code that runs | Package names and versions, once combined and renamed |
| Separate wasm modules | Binary files | Libraries compiled inside them |
A bundle is the truth about what runs, and the lockfile is the truth about what you declared. You need both.
A practical process
- Run the build as CI does, with a dry run that writes the output to a folder. The Wrangler documentation gives this form:
npx wrangler deploy --dry-run --outdir dist
- Scan the lockfile for vulnerable versions.
- Look inside the dist output for banner comments, license headers or source maps that name packages. If you keep source maps, they help map bundle code back to packages.
- Compare: for each vulnerable package in the lockfile, is its code present in the bundle? A package in node_modules that no import reaches may never ship.
- List wasm and other modules separately and note their provenance.
- Store the lockfile hash, bundle hash and compatibility date together for each deployment.
Reachability helps triage
If a vulnerable function lives in a package that your bundle includes but your code never calls, the practical risk is lower than for a package on a live code path. Reachability analysis at the function level helps you rank fixes, but it does not replace updating the package.
Watch for build tool changes
The Wrangler page warns that the esbuild version may be bumped in a Wrangler minor version, which can change bundling behavior. Pin Wrangler in your lockfile and review upgrades like any other dependency. Using the no bundle option is discouraged in most scenarios by the same documentation, and without bundling Wrangler does not process your code, so features such as polyfill injection are not available.
Try it yourself
Click through it at your own pace, or open it full screen.
Compare the count of raw findings with the count that remain after reachability. That gap is what you gain from knowing what your bundle actually calls.
Quick check
Is scanning node_modules enough for a Worker?
It lists what is installed, which can include packages that never ship. Pair it with the lockfile and a dry run of the bundle.
Does bundling remove vulnerabilities?
No. Tree shaking may drop unused code, but vulnerable code that your bundle includes still runs at the edge.
Safeguard's dependency scanning and reachability analysis work from your repository and lockfile, and a free scan is available at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.