A couple of months ago I wrote about "Node watch mode and TypeScript" which suggests using the @swc-node/register package to be able to run node on .ts file without first converting it to .js using tsc.

In Node 22, you don't even need @swc-node/register. You can use --experimental-strip-types instead. (Note the prefix "experimental"). See release notes here.

Imagine a script like this:


// example.ts

function c2f(c: number) {
  return (c * 9) / 5 + 32;
}
console.log(c2f(123));

you can execute it directly in Node v22 using:


❯ node --experimental-strip-types --no-warnings example.ts
253.4

Pretty cool! In a real project, you'll want a tsconfig.json and some automation that checks that the types are correct. Mind you, if you use VS Code, it will automatically check basic TypeScript without a tsconfig.json file:

VS Code TypeScript checking

Benchmark

From the department of highly-unscientific-benchmarks-and-fruit-comparisons, let's test the execution speed of that sample example.ts using --experimental-strip-types versus --require @swc-node/register.


❯ node --version
v22.12.0

❯ hyperfine --warmup 3 \
  "node --require @swc-node/register example.ts" \
  "node --experimental-strip-types --no-warnings example.ts"
Benchmark 1: node --require @swc-node/register example.ts
  Time (mean ± σ):     141.1 ms ±   1.4 ms    [User: 128.9 ms, System: 14.4 ms]
  Range (min … max):   139.5 ms … 146.1 ms    19 runs

Benchmark 2: node --experimental-strip-types --no-warnings example.ts
  Time (mean ± σ):      53.9 ms ±   1.8 ms    [User: 53.5 ms, System: 6.6 ms]
  Range (min … max):    52.2 ms …  61.4 ms    52 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on \
 a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Summary
  node --experimental-strip-types --no-warnings example.ts ran
    2.62 ± 0.09 times faster than node --require @swc-node/register example.ts

See the "Summary" part. It claims that using --experimental-strip-types is 2.6x faster than --require @swc-node/register.
But this is not fair in terms of true runtime because in this benchmark, I suspect a large majority of the runtime time is the starting up of the Node process. However, if speed matters and your .ts file is small, here lies a chance to gain some speed.

Bonus benchmark

Deno and Bun can also run .ts files without extensions. Let's, for the fun of it, compare how fast it can start that execution:


❯ deno --version
deno 2.1.3 (stable, release, aarch64-apple-darwin)
v8 13.0.245.12-rusty
typescript 5.6.2

❯ bun --version
1.1.30

❯ hyperfine --warmup 3 \
  "node --require @swc-node/register example.ts" \
  "node --experimental-strip-types --no-warnings example.ts" \
  "bun run example.ts" \
  "deno run example.ts"
Benchmark 1: node --require @swc-node/register example.ts
  Time (mean ± σ):     143.8 ms ±   7.0 ms    [User: 130.5 ms, System: 14.9 ms]
  Range (min … max):   138.8 ms … 166.5 ms    20 runs

Benchmark 2: node --experimental-strip-types --no-warnings example.ts
  Time (mean ± σ):      55.6 ms ±   4.8 ms    [User: 54.0 ms, System: 7.1 ms]
  Range (min … max):    52.2 ms …  81.2 ms    45 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on \
 a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 3: bun run example.ts
  Time (mean ± σ):       9.5 ms ±   0.8 ms    [User: 5.0 ms, System: 3.8 ms]
  Range (min … max):     8.1 ms …  13.1 ms    201 runs

Benchmark 4: deno run example.ts
  Time (mean ± σ):      23.5 ms ±  14.9 ms    [User: 14.5 ms, System: 7.2 ms]
  Range (min … max):    20.0 ms … 182.4 ms    119 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on \
 a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Summary
  bun run example.ts ran
    2.47 ± 1.57 times faster than deno run example.ts
    5.82 ± 0.70 times faster than node --experimental-strip-types --no-warnings example.ts
   15.06 ± 1.44 times faster than node --require @swc-node/register example.ts

Before focusing on the summary comparison, keep in mind that the mean time to run it is 143.8ms which is fast enough for executing scripts.

Comments

Your email will never ever be published.

Previous:
An ideal pattern to combine React Router with TanStack Query November 18, 2024 React, JavaScript
Next:
How I built an index of my blog posts on my GitHub profile page December 13, 2024 Node, GitHub
Related by category:
Switching from Next.js to Vite + wouter July 28, 2023 JavaScript, Node
How to SSG a Vite SPA April 26, 2025 JavaScript
fnm is much faster than nvm. December 28, 2023 Node
swr compared to @tanstack/react-query August 30, 2024 JavaScript
Related by keyword:
ts-node vs. esrun vs. esno vs. bun August 28, 2023 Node, JavaScript
In TypeScript, how to combine known and unknown keys to an object July 3, 2024 JavaScript
Node watch mode and TypeScript July 21, 2024 Node, JavaScript
How to extend a function in TypeScript without repeating the signature types October 16, 2024 JavaScript
OSZAR »