The tsbuild command is TypeScript's command-line interface for building multi-project solutions with project references. It is invoked via tsc --build (or tsc -b) and provides incremental compilation capabilities across referenced projects, determining which projects need rebuilding based on their dependencies, timestamps, and output signatures.
For information about the BuilderProgram interface and build state management, see BuilderProgram and State (8.3) For details on project references configuration, see Project References (8.2) For up-to-date checking logic, see Up-to-Date Checking (8.4)
The tsbuild command is invoked through the standard tsc compiler entry point. The entry point in src/tsc/tsc.ts24 calls executeCommandLine, which parses the arguments. If the --build or -b flag is present, the compiler executes the solution building logic instead of a standard single-project compilation.
| Option | Short | Description |
|---|---|---|
--verbose | -v | Enable verbose logging of build operations. |
--dry | -d | Perform a dry run without emitting files. |
--force | -f | Force rebuild all projects regardless of status. |
--clean | Remove output files and .tsbuildinfo instead of building. | |
--watch | -w | Enable watch mode for continuous builds. |
--incremental | -i | Enable incremental compilation (default for composite projects). |
--traceResolution | Log module resolution details. | |
--explainFiles | Explain why files are included in the compilation. |
Sources: src/tsc/tsc.ts1-25 src/compiler/watch.ts161-170 src/testRunner/unittests/tsbuild/sample.ts33-125
The tsbuild command supports several distinct modes of operation that govern how the project graph is traversed and processed.
Title: tsbuild Mode Selection and Data Flow
In normal build mode, tsbuild evaluates each project's UpToDateStatus to determine if it needs rebuilding. The status types are defined by the UpToDateStatusType enum in src/compiler/tsbuild.ts10-38
Clean mode (--clean) removes all build outputs for specified projects. This includes .js, .d.ts, source maps, and the .tsbuildinfo files. The implementation is tested in scenarios where projects are cleaned in or out of build order src/testRunner/unittests/tsbuild/sample.ts81-115
Force mode (--force) sets the status to UpToDateStatusType.ForceBuild src/compiler/tsbuild.ts37 bypassing all timestamp and signature checks to perform a fresh compilation src/testRunner/unittests/tsbuild/sample.ts117-125
Sources: src/compiler/tsbuild.ts10-38 src/testRunner/unittests/tsbuild/sample.ts72-125
The heart of tsbuild is the UpToDateStatus calculation. This logic determines whether a project is current with respect to its inputs and upstream dependencies.
The system uses a variety of status interfaces defined in the Status namespace src/compiler/tsbuild.ts58-174:
UpToDate: The project is current. It may include a newestInputFileTime to compare against downstream projects src/compiler/tsbuild.ts79-87OutputMissing: One or more outputs (like a .js or .d.ts file) are missing src/compiler/tsbuild.ts92-98OutOfDateWithSelf: An input file is newer than an output file src/compiler/tsbuild.ts109-113UpstreamOutOfDate: The project depends on an out-of-date project src/compiler/tsbuild.ts135-138UpToDateWithUpstreamTypes: A special status where upstream inputs are newer, but their .d.ts signatures haven't changed, allowing a "pseudo-build" (touching timestamps) instead of a full re-emit src/compiler/tsbuild.ts12-18Project names passed to the command line are resolved via resolveConfigFileProjectName src/compiler/tsbuild.ts177-183 If a directory is provided, it looks for tsconfig.json within that directory.
Title: Code Entity Mapping - Status and Resolution
Sources: src/compiler/tsbuild.ts10-183
tsbuild relies on .tsbuildinfo files to persist state between runs. This state is represented by the BuilderState interface src/compiler/builderState.ts62-98
fileInfos: A map of file paths to FileInfo, containing the version (hash) and the .d.ts signature of the file src/compiler/builderState.ts66referencedMap: Tracks dependencies between files to determine the impact of a change src/compiler/builderState.ts72semanticDiagnosticsPerFile: Caches type-checking results so that only changed or affected files need re-checking src/compiler/builder.ts213emitSignatures: Stores hashes of the emitted .d.ts files to detect if a change in a project actually changes the public API consumed by others src/compiler/builder.ts172If the .tsbuildinfo file is corrupted or created by a different TypeScript version, the build system triggers a full rebuild. The status TsVersionOutOfDate is used when the version field in the build info does not match the current compiler version src/compiler/tsbuild.ts156-159
Sources: src/compiler/builderState.ts62-109 src/compiler/builder.ts133-213 src/compiler/tsbuild.ts156-159
tsbuild constructs a dependency graph from the references field in tsconfig.json. It ensures that projects are built in topological order.
Title: Project Reference Dependency Flow
When a file changes, the BuilderProgram determines the "affected" files. This includes files that import the changed file, and if the change affects the global scope, it may include all files in the project src/compiler/builderState.ts107
Sources: src/testRunner/unittests/tsbuild/sample.ts31-149 src/compiler/builderState.ts104-109
When running with --watch, tsbuild uses WatchStatusReporter to provide feedback to the user src/compiler/watch.ts193-213
Diagnostics are formatted using FormatDiagnosticsHost src/compiler/watch.ts114-118 In watch mode, the compiler can clear the screen unless preserveWatchOutput is enabled src/compiler/watch.ts146-159
The system tracks file changes and triggers partial builds. If a change in an upstream project does not change its .d.ts output (e.g., only a comment change or a private implementation change), downstream projects are not fully rebuilt, significantly improving performance src/testRunner/unittests/tsbuild/sample.ts139-143
Sources: src/compiler/watch.ts114-213 src/testRunner/unittests/tsbuild/sample.ts133-149
Refresh this wiki