CodeVetter
← All unpacks
CodeVetter · Repo Unpack evidence

evanw/esbuild

Scanned commit f6058f8364 dated 2026-08-09 — last upstream commit. Generated by codevetter 1.12.0 on 2026-09-22.

github.com/evanw/esbuild ↗ · 334 files · 8.5 MB

Website | Getting started | Documentation | Plugins | FAQ Why? Our current build tools for the web are 10-100x slower than they could be: The main goal of the esbuild bundler project is to bring about a new era of build tool performance, and create an easy-to-

Deep analysis by cli:grok via the grok CLI on 2026-09-22 (497s) — every claim below links to its cited source files.

Overview

esbuild 0.28.2 is a Go bundler and minifier for JavaScript, TypeScript, JSX, JSON, and CSS. It is used from a native CLI (cmd/esbuild), a Go library (pkg/api and pkg/cli), and an npm package whose JavaScript spawns a long-lived native binary or a WebAssembly build. The pipeline is two phases, scan then compile, with three full AST passes, parallel parsing, and incremental rebuilds that reuse immutable cached ASTs instead of a content-addressed JS cache. Releases are a matrix of optional @esbuild/* native packages plus esbuild-wasm, published by GitHub Actions when version.txt changes on main.

System map

The module is github.com/evanw/esbuild. The process entry is cmd/esbuild, which either runs the CLI or a stdin/stdout service. Bundling lives under internal/ and is wrapped by pkg/api. There is no database: inputs are files or stdin, outputs are files, stdout, or in-memory bytes. The JS API in lib/ is compiled into the published npm packages and is not a separate server. Official builds pin Go 1.26.5, keep the language at Go 1.13, and disable cgo.

Feature catalog

User-facing features are the CLI flag set, the Go and JavaScript build/transform/context APIs, plugins, a local HTTP dev server, polling watch mode, and packaging for many OS/CPU targets plus WASM. Loaders cover JS, JSX, TS, TSX, CSS (including CSS modules), JSON, and several asset loaders. React appears only as a test dependency in scripts/package.json, not as a product UI.

Data flow

CLI arguments and JS option objects become config.Options and entry points. ScanBundle walks the graph in parallel: resolve, onLoad, parse, then enqueue imports. Cached ASTs must stay immutable. Compile clones the linker graph, tree-shakes, splits chunks, prints, and optionally writes files. Transform skips the real filesystem and feeds stdin bytes through the same two phases. The dev server serves the latest in-memory output instead of those files.

Behavior traces

Three flows matter: process startup (CLI versus service), a full bundle (scan, link, write), and the JS client attaching to that service. Watch and serve sit on the same Context and reuse rebuild. Transform is the bundle path with a mock filesystem and no entry-point files.

Testing signals

Go tests use the standard testing package and cover cmd, internal, and pkg. Bundler expectations are snapshot files updated with UPDATE_SNAPSHOTS=1. A second layer of Node scripts drives the real binary, the JS API, plugins, source maps, and WASM. CI splits fast race tests, slow compatibility suites, an old Go 1.13 job, tag validation, and a 6-hour install matrix. There is no separate browser product to test; React in scripts is a fixture dependency.

Risk map

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.

Extension points

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.

Contributor handoff

Start with the architecture doc, the Makefile, and the three public edges (CLI, pkg/api, lib service protocol). Keep Go 1.13, the single dependency pin, and the path/filepath ban. Do not hand-edit published npm trees. Version changes are a release. Parser and linker edits need snapshot and JS API tests, and cached ASTs must stay immutable.

Languages

LanguageFilesShare of source
Go15779%
Markdown48docs/config
JSON46docs/config
JavaScript2211%
TypeScript189%
HTML5docs/config
YAML4docs/config
CSS1docs/config

Start reading here

Probable source entrypoint: cmd/esbuild — inferred from the directory tree and manifest, not the upstream docs.

Source roots

lib/ (15 files) pkg/ (13 files)

Source layout — lib/

PathFiles
lib/npm/5
lib/shared/5
lib/README.md1
lib/package.json1
lib/tsconfig-deno.json1
lib/tsconfig-nolib.json1
lib/tsconfig.json1

Repository structure

Top-level pathFiles
internal/154
npm/60
scripts/30
lib/15
pkg/13
require/13
compat-table/11
cmd/7

Docs found: LICENSE.mdREADME.mddocs/architecture.mddocs/development.md

Package

go.mod — github.com/evanw/esbuild, 0 declared dependencies.

CI & config entrypoints

Structural health signals

Average score 6.7/10 across 96 analyzed source files; 34 hotspots surfaced.

These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.

Recent history