This page documents the hereby-based build system used in the TypeScript repository, covering the task definitions in Herebyfile.mjs, the build outputs produced, and how to invoke common build tasks. For information about running the full test suite, see Test Infrastructure. For baseline management, see Test Baseline Management.
The repository uses `hereby` as its task runner. hereby is an ESM-first build tool that reads exported task() declarations from a file named Herebyfile.mjs. All major build steps — compiling TypeScript sources, bundling output files, generating diagnostics, building library declaration files, and running tests — are expressed as named tasks in Herebyfile.mjs
The npm run build scripts in package.json delegate to hereby:
| npm script | hereby equivalent |
|---|---|
npm run build | hereby local && hereby tests |
npm run build:compiler | hereby local |
npm run build:tests | hereby tests |
npm run lint | hereby lint |
npm run clean | hereby clean |
Sources: package.json89-101 Herebyfile.mjs1-50
The following diagram shows the dependency relationships among the major tasks defined in Herebyfile.mjs.
Figure: Major hereby task dependency graph
Sources: Herebyfile.mjs416-680
All build artifacts land under built/local/. The following table maps tasks to their primary output files.
| Task | Source Entry Point | Output File |
|---|---|---|
tsc | src/tsc/tsc.ts | built/local/tsc.js |
services | src/typescript/typescript.ts | built/local/typescript.js |
tsserver | src/tsserver/server.ts | built/local/tsserver.js |
lssl | (generated stub) | built/local/tsserverlibrary.js |
dts-services | built/local/typescript/typescript.d.ts | built/local/typescript.d.ts |
dts-lssl | (generated stub) | built/local/tsserverlibrary.d.ts |
tests | src/testRunner/_namespaces/Harness.ts | built/local/run.js |
typings-installer | src/typingsInstaller/nodeTypingsInstaller.ts | built/local/typingsInstaller.js |
watch-guard | src/watchGuard/watchGuard.ts | built/local/watchGuard.js |
lib | src/lib/*.d.ts + src/lib/libs.json | built/local/lib.*.d.ts |
generate-types-map | src/server/typesMap.json | built/local/typesMap.json |
Sources: Herebyfile.mjs416-665
entrypointBuildTaskThe function entrypointBuildTask Herebyfile.mjs310-413 is the central factory for building each binary artifact. For each entry point it creates four subordinate tasks:
| Subtask name | Purpose |
|---|---|
build-<name> | Runs tsc --build on the source project |
bundle-<name> | Runs esbuild to bundle source files |
shim-<name> | Writes a CJS module that re-exports the built output |
watch-<name> | Runs project in watch mode (esbuild or tsc --watch) |
The main <name> task is an aggregate that depends on either [bundle-<name>] or [build-<name>, shim-<name>], depending on whether the --bundle flag is set.
Figure: entrypointBuildTask structure for tsc
Sources: Herebyfile.mjs310-427
createBundlerThe createBundler function Herebyfile.mjs180-293 wraps esbuild to produce a single CJS file from each TypeScript entry point. Key esbuild options used:
es2020, node14.17cjslinkedexternal (Node.js built-ins not inlined)Special handling applies to typescript.js (the services artifact):
exportIsTsObject: true — wraps the bundle so the ts global variable is set, for Monaco compatibility. After bundling, a post-process plugin rewrites esbuild's __toCommonJS helper and restores require calls Herebyfile.mjs215-261The tsserver task uses usePublicAPI: true, which redirects imports of src/typescript/typescript.ts to a runtime require("./typescript.js") instead of bundling it inline Herebyfile.mjs202-212
Sources: Herebyfile.mjs180-293
generateLibsThe lib task reads the manifest at src/lib/libs.json to discover all standard library declaration files, prepends the copyright header, and copies each one to built/local/lib.<name>.d.ts Herebyfile.mjs51-80
generateDiagnosticsThe generate-diagnostics task runs scripts/processDiagnosticMessages.mjs against src/compiler/diagnosticMessages.json, producing:
src/compiler/diagnosticInformationMap.generated.tssrc/compiler/diagnosticMessages.generated.jsonThis task is a prerequisite for all compiler-related builds because the generated file is imported by compiler source Herebyfile.mjs82-102
dtsServices and dtsLsslDeclaration files are bundled using scripts/dtsBundler.mjs. The bundler reads the compiled built/local/typescript/typescript.d.ts and emits two files:
built/local/typescript.d.ts — public API onlybuilt/local/typescript.internal.d.ts — public + internal APItsserverlibrary.d.ts and tsserverlibrary.internal.d.ts are generated as simple re-export stubs pointing at the above Herebyfile.mjs442-530
Sources: Herebyfile.mjs442-530 scripts/dtsBundler.mjs1-40
Options are parsed from process.argv by scripts/build/options.mjs using minimist. They apply globally to all tasks in a single hereby invocation.
| Flag | Default | Description |
|---|---|---|
--bundle | true | Use esbuild bundling; set --no-bundle to use tsc shims |
--typecheck | true | Run type checking alongside bundling |
--light | true | Run fewer verifications in tests |
--tests / -t | — | Regex filter for test names |
--runners / --ru | — | Comma-separated list of test runner kinds |
--workers / -w | cpu_count - 1 | Parallel worker count |
--coverage | false | Collect c8 coverage |
--dirty | false | Skip cleaning test output dirs before running |
--failed | false | Run only tests listed in .failed-tests |
--ci | auto | CI mode (uses env var CI) |
--fix | false | Auto-fix lint and knip issues |
--timeout | 40000 | Per-test timeout in ms |
Sources: scripts/build/options.mjs1-91
scripts/build/utils.mjsProvides shared utilities used throughout the build:
| Export | Purpose |
|---|---|
exec(cmd, args, opts) | Spawns a process; rejects on nonzero exit |
rimraf(p) | Recursively deletes a path |
needsUpdate(source, dest) | Compares mtimes to skip unnecessary work |
memoize(fn) | Caches the result of a zero-arg function |
Deferred | Promise with external resolve/reject |
Debouncer | Coalesces repeated calls into one deferred action |
readJson(jsonPath) | Reads JSONC files using jsonc-parser |
getDiffTool() | Reads the DIFF env var for baseline diffing |
Sources: scripts/build/utils.mjs1-247
scripts/build/tests.mjsProvides runConsoleTests scripts/build/tests.mjs34-188 which is called by the runtests and runtests-parallel tasks. It:
tests/baselines/local/ directory (unless --dirty)test.config JSON file read by the test runnerc8Also exports localBaseline (tests/baselines/local/) and refBaseline (tests/baselines/reference/) path constants.
Sources: scripts/build/tests.mjs1-233
scripts/build/projects.mjsExports buildProject, cleanProject, and watchProject (not shown in full but referenced throughout Herebyfile.mjs). Each calls the TypeScript compiler in build mode (--build) against a tsconfig.json found under the named project directory (e.g. src/tsc, src/typescript, src/tsserver).
Sources: Herebyfile.mjs16-19
For tsc, tsserver, and typings-installer, a compile-cache shim is injected when enableCompileCache: true is set. This shim is written to the primary output path (e.g. built/local/tsc.js), while the actual bundle moves to built/local/_tsc.js. The shim calls require("node:module").enableCompileCache() before loading the real module, enabling Node.js's V8 code cache for faster startup Herebyfile.mjs320-345
The localize task Herebyfile.mjs122-130 invokes scripts/generateLocalizedDiagnosticMessages.mjs, which converts LCL files under src/loc/lcl/<locale>/ into locale-specific built/local/<locale>/diagnosticMessages.generated.json files. It also produces the .lcg file at built/local/enu/diagnosticMessages.generated.json.lcg for the localization team. For more detail, see Diagnostic Message Localization.
Full compiler build:
hereby local
Minimal build (tsc + tsserver only):
hereby min
Build + run all tests (parallel):
hereby runtests-parallel
Run a specific test:
hereby runtests --tests=someTestName
Lint the codebase:
hereby lint
Check formatting:
hereby check-format
Accept new baselines after a change:
hereby baseline-accept
For detailed test options and runner kinds, see Test Infrastructure. For baseline workflows, see Test Baseline Management.
Sources: Herebyfile.mjs666-900 scripts/build/options.mjs1-91 package.json89-101
Refresh this wiki
This wiki was recently refreshed. Please wait 4 days to refresh again.