Open-Source Wikis

/

TypeScript

/

How to contribute

/

Tooling

microsoft/TypeScript

Tooling

The build, format, lint, and packaging tools the repo depends on. All are dev-only — typescript itself ships with zero runtime dependencies.

Build runner: hereby

hereby is a small gulp-style task runner. Tasks are declared in Herebyfile.mjs at the repo root. Common targets:

Task What it does
local Build the compiler into built/local/
clean Delete built/local/
tests Build the test infrastructure (built/local/run.js)
runtests Run all tests (sequential)
runtests-parallel Run tests across worker processes
lint ESLint over src/
format dprint formatter over the entire repo
LKG Promote built/local/ to lib/ (the bootstrap LKG)
generate-diagnostics Regenerate src/compiler/diagnosticInformationMap.generated.ts from the JSON source
knip Run knip dead-code detection
baseline-accept Promote tests/baselines/local/ to tests/baselines/reference/
diff Show baseline diff via $DIFF
build-tests Compile built/local/run.js

Subtasks live under scripts/build/: projects.mjs, tests.mjs, localization.mjs, options.mjs, utils.mjs. Each is invoked by Herebyfile.mjs and isolates a coherent slice of the build.

Bundler: esbuild

The compiler bundles itself with esbuild. The relevant entry points produce:

  • lib/tsc.jstsc executable.
  • lib/tsserver.jstsserver executable.
  • lib/typescript.js — public API.
  • lib/typingsInstaller.js — ATA helper.
  • lib/watchGuard.js — Windows watcher probe.

Bundling lets each entry start without requiring hundreds of TypeScript source files at runtime.

Declaration bundler: scripts/dtsBundler.mjs

The public lib/typescript.d.ts is produced by scripts/dtsBundler.mjs. It walks the src/typescript/_namespaces barrel, follows references, strips @internal-marked exports, and produces a single declaration file. This is what npm installers see.

Formatter: dprint

dprint is a Rust-based formatter configured in .dprint.jsonc. It runs over the whole repo via hereby format. The configuration sets two-space indentation, double-quoted strings, semicolons, and TypeScript-friendly line wrapping.

Linter: eslint

ESLint 10 with typescript-eslint and several local rules. Configuration: eslint.config.mjs (flat config). Local rules live under scripts/eslint/rules/:

  • argument-trivia — argument-list whitespace.
  • debug-assert — prefer Debug.assert* over Node's assert.
  • js-extensions — enforce .js extension on relative imports.
  • jsdoc-format — well-formed JSDoc.
  • no-array-mutating-method-expressions — flags arr.sort() as expressions.
  • no-direct-import — sibling modules must go through _namespaces/.
  • no-in-operator — disallow in for property tests.
  • no-keywords — disallow accidental reserved-word identifiers.
  • only-arrow-functions — discourage function expressions.

Each rule has its own .cjs file plus a corresponding test under scripts/eslint/tests/.

Dead-code detection: knip

Knip runs via hereby knip and is configured in knip.jsonc. It reports unused exports, unused dependencies, and unused files. The team treats new findings as cleanup opportunities, not hard errors.

Coverage: c8 + monocart

hereby runtests --coverage instruments the test run with c8 (configured in .c8rc.json) and generates LCov + monocart reports under coverage/. CI surfaces the totals via Codecov (.github/codecov.yml).

Diagnostic generator: scripts/processDiagnosticMessages.mjs

scripts/processDiagnosticMessages.mjs reads src/compiler/diagnosticMessages.json and produces src/compiler/diagnosticInformationMap.generated.ts. Always run hereby generate-diagnostics after editing the JSON.

Localisation: scripts/generateLocalizedDiagnosticMessages.mjs

The localisation team produces .lcl files under src/loc/lcl/<locale>/. The generator script reads them, validates against the master diagnosticMessages.json, and produces per-locale diagnosticMessages.generated.json files under built/local/<locale>/.

Pre-commit hooks (optional)

scripts/link-hooks.mjs (invoked via npm run setup-hooks) installs the repo's hook scripts into .git/hooks/. The hooks live in scripts/hooks/. They check formatting and lint before commit. Setup is opt-in.

CI

GitHub Actions workflows under .github/workflows/:

  • ci.yml — main per-PR pipeline: build, lint, test on Linux/macOS/Windows + Node LTS.
  • nightly.yaml — publishes typescript@next.
  • lkg.yml — automation for promoting LKG.
  • scorecard.yml — OSSF Scorecard.
  • codeql.yml — security scanning.
  • dependabot.yml — dependency bumps.
  • accept-baselines-fix-lints.yaml — opt-in workflow that runs hereby baseline-accept and hereby lint --fix on a PR branch.

Azure Pipelines is used for releases (azure-pipelines.release.yml, azure-pipelines.release-publish.yml).

Container

/.devcontainer/ provides a devcontainer config for VS Code's Dev Containers extension and GitHub Codespaces. The image bundles Node, npm, and the dev tools above.

Versioning and release

package.json declares version: "6.0.0". Pre-release versions go through scripts/configurePrerelease.mjs and a release-branch workflow that flips the version and publishes nightlies under the typescript@next tag.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Tooling – TypeScript wiki | Factory