Skip to content

Build1 publisher3 min readPublished

The 2-4 seconds you pay per file: batch tsc once per agent session, not once per edit

A dev.to writeup on Claude Code hooks puts a number on a common configuration mistake: the TypeScript compiler costs seconds of startup before it checks anything.

The Engineer · Build desk

Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction

What happened

  • tsc takes 2-4 seconds just to start up: booting the Node.js process, parsing tsconfig.json and loading type definition files, all of which repeats on every invocation.
  • In a monorepo, the per-file tsc launch cost repeats per package.
  • Days where you touch 100 files during a Claude Code session are not unusual, and launching tsc each time pushes the cumulative cost into minutes; the author's reported symptom is that the TypeScript check runs every single time and the response keeps stalling.
  • Claude Code hooks are called synchronously; Claude stops until the hook finishes, so the next operation is blocked until tsc completes.
  • The author argues the problem is not 'checking' but 'checking every time', noting that IDEs running whole-project checks on save do not stress users because UI response and the background process are decoupled.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

A dev.to post on Claude Code hook configuration makes one narrow, checkable claim worth acting on: `tsc` needs 2 to 4 seconds just to boot the Node process, parse `tsconfig.json` and load type definitions, and that cost repeats on every invocation [1]. Wire the compiler into a per-edit hook and you pay it once per file touched; batch it into a single run at the end of the turn and you pay it once per session [6].

The arithmetic is the whole argument. The author reports that days where an agent session touches 100 files are not unusual, and that per-file launches push the cumulative cost into minutes [3]. At 2 to 4 seconds of startup, 100 files is 200 to 400 seconds, or roughly 3.3 to 6.7 minutes of process boot with zero type checking done [1]. In a monorepo the multiplier gets worse, because the startup repeats per package [2].

The reason this hurts more than the equivalent save hook in an editor is scheduling. Claude Code hooks are called synchronously, so the agent blocks until the hook returns [4]. The author's framing is that an IDE running a whole-project check on save does not bother anyone because the UI and the background process are decoupled, and that the problem here is not checking but checking every time [5]. His description of the naive setup is slightly muddled: he describes the obvious wiring as Prettier on PostToolUse and the compiler on Stop [16], while the symptom he reports is the type check firing on every write [3]. The mechanism is clear enough regardless. Anything expensive in a PostToolUse hook is a stall the agent eats before its next tool call.

The fix is a two-file split. `post-edit-accumulator.js` runs on PostToolUse and does nothing but stack paths; `stop-format-typecheck.js` runs on Stop and processes them in bulk [8]. The accumulator tests each path against `/\.(ts|tsx|js|jsx)$/` and appends it with `appendFileSync` [9], chosen because Claude Code sometimes fires tool calls in parallel, meaning several hook processes can write at once and an atomic append is the cheap way to survive that [10]. Paths land in `/tmp/ecc-edited-{sessionId}.txt`, one per line, duplicates allowed, scoped to the session [11]. The Stop hook reads that file and immediately unlinks it to prevent double processing, dedupes with a `Set`, groups by project root for one formatter pass (`biome check --write` or `prettier --write`), and groups by `tsconfig.json` for one `npx tsc --noEmit` per config [12]. Errors are filtered to lines touching the edited files, capped at 10, and written to stderr [13].

The claimed result is that a 50-file session launches `tsc` 1 to 3 times rather than 50 [7]. On the author's own startup figure that is 100 to 200 seconds of boot replaced by 2 to 12, a saving of roughly 88 to 198 seconds per session [2].

Treat the rest of the post with more distance. The author frames this inside a personal revenue arc ending at 1.2 million yen a month [15], and credits about half of his increased workload and code quality to accumulated environment work [14]. None of that is verifiable and none of it is needed; the startup number stands on its own.

What to watch: the Stop-only design means type errors surface at the end of a turn, not at the edit that caused them, so measure whether your agent wastes more time building on a broken file than it saved on process boot. Also check the unlink-on-read step under parallel Stop events, and confirm the 10-line error cap is not hiding the failure that matters [12][13].

Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories