Skip to content
Latchkey

ts-node vs SWC: Running TypeScript Faster in CI

ts-node runs TypeScript through tsc; pairing it with the SWC register (or @swc-node) swaps in Rust-speed transpiling for much faster execution.

ts-node executes TypeScript via the TypeScript compiler. The SWC approach (ts-node's --swc flag or @swc-node/register) transpiles with SWC in Rust for far faster startup, at the cost of not running full type-checking during execution.

ts-nodeSWC (register)
Transpile enginetscSWC (Rust)
Startup speedSlowerMuch faster
Type checkingOptional (slower)No (strip only)
ESM supportWorks (config)Works
Best forType-aware executionFast script/test execution

In CI

Plain ts-node can type-check as it runs but is the slowest option; using the SWC register (or ts-node --swc) keeps the same workflow while transpiling far faster, which trims script and test startup. As with other fast transpilers, SWC does not type-check, so run tsc --noEmit separately. For sheer execution speed in CI, the SWC path wins.

Type-check separately

Add a tsc --noEmit step (in parallel) for type safety since SWC only strips types. Both run on CI runners; faster managed runners shorten long type-check passes on large codebases.

The switching cost is mostly in the parts nobody lists

  • Assertions and mocks usually port mechanically when the target implements a compatible API; custom transformers and framework plugins do not.
  • Snapshot formats differ between runners, so plan to regenerate and review rather than port.
  • Run both suites in parallel in CI for a period and diff the results. A migration that changes which tests fail is not a migration, it is a regression you have not found yet.
  • Coverage numbers move on a runner change even when the tests do not, because instrumentation differs. Re-baseline any coverage gate deliberately.

The verdict

Want the fastest TypeScript execution: ts-node with the SWC register (or @swc-node), plus a separate tsc --noEmit check. Need type-aware execution in one tool: plain ts-node. Most pipelines split speed from type-checking.

Frequently asked questions

ts-node vs SWC: Running TypeScript Faster in CI?
ts-node executes TypeScript via the TypeScript compiler. The SWC approach (ts-node's --swc flag or @swc-node/register) transpiles with SWC in Rust for far faster startup, at the cost of not running full type-checking during execution.
In CI?
Plain ts-node can type-check as it runs but is the slowest option; using the SWC register (or ts-node --swc) keeps the same workflow while transpiling far faster, which trims script and test startup. As with other fast transpilers, SWC does not type-check, so run tsc --noEmit separately. For sheer execution speed in CI, the SWC path wins.
Type-check separately?
Add a tsc --noEmit step (in parallel) for type safety since SWC only strips types. Both run on CI runners; faster managed runners shorten long type-check passes on large codebases.
Which should I choose?
Want the fastest TypeScript execution: ts-node with the SWC register (or @swc-node), plus a separate tsc --noEmit check. Need type-aware execution in one tool: plain ts-node. Most pipelines split speed from type-checking.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card