# Extension points — evanw/esbuild

> Canonical page: https://codevetter.com/unpack/esbuild/extension-points

# Extension points — evanw/esbuild

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

The supported plug-in surface is the plugin object with onStart, onResolve, onLoad, onEnd, and onDispose, available from Go, the CLI via RunWithPlugins, and the JS service. Loaders, defines, inject files, and the runtime helper string are the other intended extension points. New OS targets are new directories under npm/@esbuild plus installer tables, not a plugin.
- api.Plugin is Name plus Setup(PluginBuild). PluginBuild registers OnStart, OnEnd, OnResolve(filter, namespace), OnLoad(filter, namespace), OnDispose, and a Resolve helper. SideEffects is a bool-like enum on results. — [pkg/api/api.go#L566-L641](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/api.go#L566-L641)
- cli.RunWithPlugins appends caller plugins after parse, and --analyze is itself added as a plugin that forces Metafile true. Native Go embedding is the supported way to add plugins without the JS service. — [pkg/cli/cli.go#L34-L37](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/cli/cli.go#L34-L37) [pkg/cli/cli_impl.go#L1213-L1220](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/cli/cli_impl.go#L1213-L1220) [pkg/cli/cli_impl.go#L1194-L1196](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/cli/cli_impl.go#L1194-L1196)
- JS plugins are declared as BuildPlugin records (name, onStart, onEnd, onResolve/onLoad id+filter+namespace) and sent in the build packet. Callbacks round-trip as resolve and on-end requests. — [lib/shared/stdio_protocol.ts#L42-L65](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/shared/stdio_protocol.ts#L42-L65) [cmd/esbuild/service.go#L245-L262](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/service.go#L245-L262) [cmd/esbuild/service.go#L418-L429](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/service.go#L418-L429)
- config.CompileFilterForPlugin compiles each OnResolve and OnLoad filter regex and tags errors with the plugin name and hook kind. That is the validation gate for new plugin filters. — [pkg/api/api_impl.go#L1952-L1963](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/api_impl.go#L1952-L1963) [pkg/api/api_impl.go#L2030-L2040](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/api_impl.go#L2030-L2040) [internal/config/config.go#L756](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/config/config.go#L756)
- parseFile's switch on config.Loader is the dispatch table for new content types. Adding a loader means a Loader constant, an extension map entry, a CLI name, and a branch that produces either a JSRepr or CSSRepr. — [pkg/api/api.go#L141-L161](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/api.go#L141-L161) [internal/bundler/bundler.go#L267-L308](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/bundler/bundler.go#L267-L308) [cmd/esbuild/main.go#L40-L43](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/main.go#L40-L43)
- Architecture docs say new helper functions belong in the string inside internal/runtime/runtime.go so they are parsed as the runtime file and tree-shaken. Names must not collide with tslib helpers such as __decorate and __extends; esbuild uses its own __create, __defProp, and similar names. — [docs/architecture.md#L223-L225](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/docs/architecture.md#L223-L225) [internal/runtime/runtime.go#L19-L66](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/runtime/runtime.go#L19-L66)
- Compile-time substitution is --define:K=V and the Define map. Dead-code elimination of require() inside folded branches is documented with the React process.env.NODE_ENV pattern. --inject:F and --pure:N are the other per-build hooks that do not require a plugin. — [docs/architecture.md#L92-L104](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/docs/architecture.md#L92-L104) [cmd/esbuild/main.go#L35](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/main.go#L35) [cmd/esbuild/main.go#L83-L84](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/main.go#L83-L84) [cmd/esbuild/main.go#L119](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/main.go#L119)
- Resolver namespaces are part of logger.Path. The file namespace is special-cased for canonical Windows paths, relative rewriting, and overwrite checks. dataurl is a namespace handled by resolver.ParseDataURL. Plugins can return other namespaces from OnResolve. — [internal/bundler/bundler.go#L1550-L1553](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/bundler/bundler.go#L1550-L1553) [internal/bundler/bundler.go#L1611-L1625](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/bundler/bundler.go#L1611-L1625) [internal/bundler/bundler.go#L3137-L3142](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/bundler/bundler.go#L3137-L3142)
- Engine support is data, not code: internal/compat feature bits plus tables generated from compat-table (MDN, caniuse, compat-table). --target and --supported:F=true|false are the user-facing overrides. — [compat-table/package.json#L2-L9](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/compat-table/package.json#L2-L9) [internal/compat/compat.go#L14-L21](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/compat/compat.go#L14-L21) [cmd/esbuild/main.go#L53-L54](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/main.go#L53-L54) [cmd/esbuild/main.go#L130](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/main.go#L130)
- A new platform package is a directory under npm/@esbuild, plus entries in node-platform.ts maps and esbuild.binaryHashes. RUNBOOK.md says to publish an empty 0.0.1 package, set the esbuild npm user as sole maintainer, and add this repo's publish.yml as the trusted publisher. — [RUNBOOK.md#L40-L64](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/RUNBOOK.md#L40-L64) [lib/npm/node-platform.ts#L22-L55](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-platform.ts#L22-L55) [npm/esbuild/package.json#L20-L49](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/npm/esbuild/package.json#L20-L49)
- ESBUILD_BINARY_PATH is a documented external extension point. Comments in node-platform.ts and node-install.ts say not to remove it because outside code and the test suite depend on it. — [lib/npm/node-platform.ts#L7-L17](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-platform.ts#L7-L17) [lib/npm/node-install.ts#L252-L255](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/node-install.ts#L252-L255)
- Banner and footer are per output type (css or js). Injected files are turned into generated import statements in the parser before the visit pass. Both are extension points that do not add a new loader. — [cmd/esbuild/main.go#L66-L79](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/cmd/esbuild/main.go#L66-L79) [internal/js_parser/js_parser.go#L17918-L17983](https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/js_parser/js_parser.go#L17918-L17983)

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)
