Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Adding --incremental to a TypeScript check can make it slower, at least in some projects. The 3.6× slowdown and the 200 KB cache-size cutoff come from one author’s report on one project, closet-os, which runs a type check from a Claude Code post-tool hook. The report does not name the TypeScript version or the machine used. Treat its numbers as a case study and a measurement method, not as a rule that incremental checking slows down once the cache passes a fixed size. The practical answer is to measure cold and warm runs in your own repository, with your own compiler version, and choose any fallback threshold from those results.

What the report measured

The author added --incremental to a tsc check that runs from a Claude Code post-tool hook. On the closet-os project, cold runs reportedly became 3.6× slower. The author’s proposed explanation is the cost of generating and reading the .tsbuildinfo state file.

To avoid that cost on large cache files, the author wrote a shell guard. It checks the size of the build-info file and falls back to a plain tsc --noEmit when the file is larger than 204800 bytes (200 × 1024). The author says the threshold came from measurements on that one project and advises readers to find their own crossover point.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The hook and the cache location

The example stores the build-info file under node_modules/.cache and sets its path with --tsBuildInfoFile. Keeping the file out of the source tree is a reasonable choice, but it means a dependency reinstall that clears node_modules also clears the cache, and the next run is cold again.

The guard, as a sketch

The following is a simplified sketch of the pattern described in the report, not the author’s exact script. Test it on your own operating system before using it.

#!/bin/sh
# Simplified sketch of a build-info size guard. Verify before use.
BI=node_modules/.cache/tsc/project.tsbuildinfo
LIMIT=204800

if [ -f "$BI" ]; then
  if [ "$(uname -s)" = "Darwin" ]; then
    SIZE=$(stat -f %z "$BI")   # macOS (BSD stat)
  else
    SIZE=$(stat -c %s "$BI")   # Linux (GNU stat)
  fi
  if [ "$SIZE" -gt "$LIMIT" ]; then
    exec npx tsc --noEmit
  fi
fi

mkdir -p node_modules/.cache/tsc
exec npx tsc --noEmit --incremental --tsBuildInfoFile "$BI"

Notice what this sketch does once the file passes the limit: it stops using the cache, but it does not delete the file. The oversized file stays on disk until you remove it, and it keeps the guard on the plain path until then.

Rank #2
TypeScript Programming Language - Software Engineer & Coder T-Shirt
  • TypeScript implements a superset of syntax for strictly typed development, facilitating deep static analysis and enhanced development environment integration. The compiler translates source into standard script formats, ensuring parity across any runtime.
  • TypeScript is ideal for front-end developers, full-stack engineers, and software architects who build large-scale web applications. It serves those looking to improve code excellence, reduce bugs through static checking, and maintain complex projects more.
  • Lightweight, Classic fit, Double-needle sleeve and bottom hem

What TypeScript’s documentation establishes

  • Purpose. The incremental option saves information about the project graph from a previous compilation and uses it in later builds.
  • Runtime role. The TSConfig documentation for incremental states: “They are not used by your JavaScript at runtime and can be safely deleted.” Deleting the file only forces the next run to be a cold one.
  • Location. The tsBuildInfoFile option controls where the .tsbuildinfo file is written.
  • Origin of the feature. The TypeScript 3.4 release notes describe the flag as a way to use prior build information to find a less costly way to type-check and emit changes.
  • Known overhead. The TypeScript 4.3 release notes say incremental and watch modes may need initial bookkeeping, which can make the first build slower in some cases. The same notes describe later changes that defer some calculations and reduce cache size in particular examples.

The 4.3 notes describe a specific version’s behavior. They neither confirm the author’s benchmark nor show that current compiler releases have the same timing profile.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why a cold run can be slower

A cold run is one where no usable build-info file exists, either because it was deleted, was never written, or was cleared with node_modules. In that case the compiler does the bookkeeping that incremental mode needs and writes the state file, but it has no earlier state to reuse. The saving appears only on later runs, when most of the program is unchanged and the compiler can skip work it has already done.

A post-tool hook makes this distinction matter. If every invocation follows an edit, or runs in a fresh environment where the cache was cleared, the hook may pay the cold cost repeatedly and seldom reach the warm case. The report’s 3.6× figure refers to cold runs, so it should not be read as a measure of steady-state hook performance.

Where 200 KB comes from, and what it does not show

204800 bytes is 200 × 1024. In the report it is a fallback threshold chosen from one project’s measurements. It is not a TypeScript constant, and no documentation sets it. Build-info size tends to grow with project size, so it works as a rough proxy, but the same file size can come from projects with very different compile profiles. A size cutoff tells you when to re-measure, not what the timing will be.

The report does not publish a full benchmark table, the compiler version, the machine specification, or an independent reproduction. Those gaps are why the threshold should be treated as the author’s observation for one project.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to find your own crossover

  1. Record the environment. Run npx tsc --version and node --version, and note your operating system, CPU, and memory.
  2. Time the baseline. Run time npx tsc --noEmit three to five times and keep the timings.
  3. Time cold incremental runs. Before each run, delete the state file, then run mkdir -p .bench && rm -f .bench/cold.tsbuildinfo && time npx tsc --noEmit --incremental --tsBuildInfoFile .bench/cold.tsbuildinfo. Repeat three to five times.
  4. Time warm incremental runs. Without deleting the file, run time npx tsc --noEmit --incremental --tsBuildInfoFile .bench/cold.tsbuildinfo three to five times.
  5. Time the workload the hook actually sees. Edit a file the way your normal workflow does, then run the warm command and time it. A one-line edit and a large refactor can produce very different results.
  6. Record the file size. Run stat -c %s .bench/cold.tsbuildinfo on Linux or stat -f %z .bench/cold.tsbuildinfo on macOS, after the cold run and after the warm runs.
  7. Choose a policy from the data. Find the size at which your cold runs stop paying off, and set your fallback there. Re-run the measurements after upgrading TypeScript or after large changes to the project.
Factor In the closet-os report What you should record yourself
TypeScript version Not stated in the report Output of npx tsc --version
Machine and OS Not stated; the guard uses macOS and Linux stat syntax CPU, memory, OS version, and Node version
Project size One named project; no size breakdown published Number of source files and the include and exclude settings in your tsconfig
Cold timing Reported as 3.6× slower Median of repeated cold runs with the state file removed first
Warm timing No complete table published Median of repeated warm runs, with and without an edit
Cache size Fallback threshold of 204800 bytes File size after the cold run and after the warm runs
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Hook pitfalls to check

  • Exit status in pipelines. A pipeline such as tsc --noEmit | tee log.txt reports the exit status of the last command, not tsc, unless pipefail is set. The report itself describes a pipeline where capturing the final command’s status gave the wrong result. Run tsc directly, store $? immediately after it, or enable set -o pipefail in a shell that supports it.
  • Platform commands. stat takes different flags on BSD and GNU systems, so the byte-size check must be tested on each operating system where the hook runs.
  • Cache loss is harmless. Because the state file is safe to delete, a missing cache only means the next run is cold. It does not corrupt the build.

Before you rely on the hook, confirm that its output and exit codes match the workflow you intend, and that the fallback path produces the same type errors as the incremental path.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.