# Risk map — evanw/esbuild

> Canonical page: https://codevetter.com/unpack/esbuild/risk-map

# Risk map — evanw/esbuild

Scanned commit f6058f8364fe7ab91ca57a83e02577ed74c9cae4 (2026-08-09). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

esbuild treats source text as trusted and says the dev server is not a security boundary. The sharp edges are the install-time binary download, the unauthenticated local IPC service, filesystem writes at absolute paths, and the size of the parser and linker. Go 1.13 compatibility and the path/filepath ban make casual modern-Go edits break the build. The architecture doc disagrees with the CLI on whether tree shaking can be turned off.
- node-install.ts downloads missing platform binaries by running npm install of @esbuild/<pkg>@<version> via child_process.execSync, and as a last resort https.get of https://registry.npmjs.org/<pkg>/-/<tarball>.tgz. extractFileFromTarGzip pulls package/<subpath> out of the gzip. — [lib/npm/node-install.ts#L70-L103](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-install.ts#L70-L103) [lib/npm/node-install.ts#L105-L148](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-install.ts#L105-L148) [lib/npm/node-install.ts#L236-L249](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-install.ts#L236-L249)
- binaryIntegrityCheck sha256s the bytes and compares them to packageJSON['esbuild.binaryHashes'][pkg/subpath]. A missing or mismatched hash throws. The check is skipped when ESBUILD_BINARY_PATH is set and the file exists. — [lib/npm/node-install.ts#L228-L234](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-install.ts#L228-L234) [lib/npm/node-install.ts#L252-L262](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-install.ts#L252-L262) [lib/npm/node-platform.ts#L116-L125](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-platform.ts#L116-L125)
- validateBinaryVersion runs the chosen binary with --version via execFileSync and throws if stdout does not equal packageJSON.version. On macOS it special-cases _SecTrustEvaluateWithError and suggests esbuild-wasm or an older Go. — [lib/npm/node-install.ts#L20-L59](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-install.ts#L20-L59)
- The stdin/stdout service has no authentication. Any local process that can speak the length-prefixed protocol can request build, transform, serve, or resolve. --service refuses to start only when the host version string mismatches. — [cmd/esbuild/service.go#L1-L4](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/service.go#L1-L4) [cmd/esbuild/main.go#L200-L214](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/main.go#L200-L214) [lib/shared/stdio_protocol.ts#L1-L5](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/shared/stdio_protocol.ts#L1-L5)
- The Makefile comment states esbuild is not a security boundary: it transforms trusted source text and the dev server is a read-only view of source not intended for production. Serve still checks Host to block DNS rebinding and rejects Windows backslashes in URLs. — [Makefile#L66-L77](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/Makefile#L66-L77) [pkg/api/serve_other.go#L134-L162](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/serve_other.go#L134-L162)
- rebuildImpl writes output with ioutil.WriteFile at absolute paths using mode 0666, or 0777 when IsExecutable, and os.Remove on outputs that disappeared between rebuilds. AllowOverwrite is forced when Write is false so serve can use input paths as output paths. — [pkg/api/api_impl.go#L1455-L1458](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/api_impl.go#L1455-L1458) [pkg/api/api_impl.go#L1604-L1624](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/api_impl.go#L1604-L1624)
- OnLoad and OnResolve plugins supply file contents and paths. JS plugins cross the service boundary; a plugin callback can therefore cause the Go process to parse and later write whatever bytes the plugin returns. — [pkg/api/api.go#L575-L597](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/api.go#L575-L597) [internal/bundler/bundler.go#L164-L189](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/bundler/bundler.go#L164-L189) [cmd/esbuild/service.go#L245-L262](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/service.go#L245-L262)
- docs/architecture.md says tree shaking is always active and cannot be disabled. The CLI and TransformOptions both expose a tree-shaking switch, and validateTreeShaking is called from transformImpl. The architecture page is stale on that point. (inferred) — [docs/architecture.md#L114-L116](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/docs/architecture.md#L114-L116) [cmd/esbuild/main.go#L130-L131](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/main.go#L130-L131) [pkg/api/api_impl.go#L1776](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/api_impl.go#L1776)
- publish.yml has id-token: write and contents: write, builds every platform, refuses a dirty git status, installs npm 11.5.1, runs make publish-all, pushes tag v$ESBUILD_VERSION, and creates a GitHub Release from the CHANGELOG section. A version.txt push to main is the release trigger. — [.github/workflows/publish.yml#L3-L13](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/.github/workflows/publish.yml#L3-L13) [.github/workflows/publish.yml#L44-L87](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/.github/workflows/publish.yml#L44-L87) [RUNBOOK.md#L6-L24](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/RUNBOOK.md#L6-L24)
- Parser panics that are not js_lexer.LexerPanic are re-panicked in js_parser.Parse. parseFile has its own recover that turns any panic into a log error with a stack, so a parser crash becomes a failed file rather than a dead process during scan. — [internal/js_parser/js_parser.go#L17815-L17824](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/js_parser/js_parser.go#L17815-L17824) [internal/bundler/bundler.go#L257-L265](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/bundler/bundler.go#L257-L265)
- staticcheck.conf sets checks = [] and the comment says the author disabled the VS Code Go linter on purpose. Agents should not assume staticcheck is an enforced gate. — [staticcheck.conf#L1-L5](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/staticcheck.conf#L1-L5)
- ioutil is still used in api_impl.go and the install path uses sync npm install. That is consistent with the Go 1.13 floor, but edits that use newer stdlib-only APIs or generics will fail the Go 1.13 CI job even if local Go 1.26 accepts them. — [pkg/api/api_impl.go#L1599](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/api_impl.go#L1599) [go.mod#L3-L5](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/go.mod#L3-L5) [.github/workflows/ci.yml#L216-L228](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/.github/workflows/ci.yml#L216-L228)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
