kadence
Decisions

ADR-001 — TypeScript on Node as the core runtime

An empty Node process costs 40 ms of a 200 ms budget, and every other stack decision follows from paying it.

Date: 2026-09-02 · Status: accepted · Scope: stack

Context

kadence has to run through npx kadence with nothing installed first. The guardrail on CLI startup is 200 ms with 1,000 tasks.

Measured on the development machine (Node v25.8.2):

Time
Cold start of an empty Node process40 ms
Left for everything the CLI actually does160 ms

40 ms is 20% of the budget, spent before the first line of our code. This is the constraint the rest of the stack decisions hang from.

Options considered

OptionForAgainst
TypeScript + Nodenpx works with no install; the largest pool of OSS contributors; types as an executable spec for events40 ms eaten by the runtime; needs a build step
Go~2 ms start; a single static binary; ideal for a CLINo npx — Homebrew, scoop or a curl script per platform, which kills "try it in 30 seconds"
RustFastest; reliability through typesSame as Go, plus a higher barrier for contributors
Deno / BunFaster start than NodeSmaller audience; npx is still the dominant habit

Decision

TypeScript, built to ESM, targeting Node 20+. The minimum is 20 LTS rather than current: demanding a fresh Node from someone who only wants to try the tool contradicts the promise of zero setup.

Distribution is a single bundle built with esbuild. The reason is not file size but the number of filesystem calls: every import in an unbundled node_modules is a separate resolve, and those are the milliseconds measured in ADR-003.

Consequences

  • npx kadence works immediately, and the event types double as documentation.
  • 40 ms of the budget is gone for good. Every later ADR exists because that price is already paid.
  • What would make us revisit it: if profiling shows we exceed 200 ms even with an empty core, the only way out is rewriting the core in Go and giving up npx for binaries. That deserves its own ADR, and it is not taken until there are measurements on real repositories.

On this page