The Up-To-Date checking system is a core component of tsbuild (Project References) and incremental compilation. Its purpose is to determine whether a project needs to be rebuilt by comparing the state of input files against existing outputs and metadata stored in .tsbuildinfo files. This avoids redundant compilation cycles in large multi-project solutions.
The system categorizes the state of a project using the UpToDateStatusType enumeration. This status guides the SolutionBuilder on whether to skip a project, perform a full rebuild, or execute a "pseudo-build" (updating timestamps without re-emitting).
| Status Type | Description |
|---|---|
UpToDate | All inputs are older than outputs; no work needed. |
UpToDateWithUpstreamTypes | Inputs changed, but upstream .d.ts shapes are identical to previous builds. Allows pseudo-build. |
OutputMissing | A required output file (e.g., .js or .d.ts) is not found on disk. |
OutOfDateWithSelf | One or more local input files are newer than the project's outputs. |
OutOfDateWithUpstream | An upstream project dependency has newer outputs than this project's outputs. |
UpstreamOutOfDate | A dependency project is itself out of date and must be built first. |
TsVersionOutputOfDate | The version of TypeScript used for the last build differs from the current version. |
ContainerOnly | The project is a "solution" config that only references other projects. |
Sources: src/compiler/tsbuild.ts10-38 src/compiler/tsbuild.ts58-174
The check is orchestrated through the UpToDateStatus interface. The system validates the project's integrity by checking for missing files, version mismatches, and then performing a timestamp-based comparison.
The following diagram illustrates how the system resolves the status of a project.
Project Status Resolution Flow
Sources: src/compiler/tsbuild.ts40-55 src/compiler/tsbuild.ts79-87 src/compiler/tsbuild.ts109-113
A critical optimization in the up-to-date check is the use of Signatures. Instead of just checking file modification times, TypeScript calculates a hash of the generated declaration files (.d.ts).
The BuilderState interface manages the mapping of file paths to their respective signatures. If a file's text changes but its generated .d.ts shape remains the same, downstream projects may be eligible for an UpToDateWithUpstreamTypes status, preventing a cascade of rebuilds.
| Entity | Role |
|---|---|
fileInfos | Maps Path to FileInfo (version and signature). |
emitSignatures | Stores the hash of the .d.ts emitted for each file. |
useFileVersionAsSignature | Optimization to use disk versioning before computing expensive hashes. |
outSignature | The signature for projects using the --outFile option. |
Sources: src/compiler/builderState.ts62-98 src/compiler/builder.ts136-183
The following diagram bridges the high-level concepts to the internal TypeScript structures.
Entity Mapping: Up-To-Date Checking
Sources: src/compiler/tsbuild.ts41-55 src/compiler/builderState.ts62-83 src/compiler/builderState.ts104-109 src/compiler/builder.ts136-183
When a project is UpToDateWithUpstreamTypes, the compiler performs a "pseudo-build". This involves:
BuildInfo metadata is updated to reflect that the current state is valid.The OutOfDateBuildInfo status specifically tracks issues where the .tsbuildinfo file itself is corrupted or indicates a pending emit that was never completed (e.g., due to a crash or process termination).
Sources: src/compiler/tsbuild.ts14-18 src/compiler/tsbuild.ts118-124 src/compiler/builder.ts10-21
resolveConfigFileProjectName: Normalizes project names to their tsconfig.json path for consistent lookup. src/compiler/tsbuild.ts177-183createManyToManyPathMap: Used within BuilderState to track complex dependency relationships between files (e.g., which files are affected by a change in a specific module). src/compiler/builderState.ts123-169SignatureInfo: An internal enum used during testing to track how a file's signature was derived (Computed, Stored at Emit, or Version-based). src/compiler/builderState.ts56-60