tsx 4.23.15 vs ts-node 10.9.2 on TypeScript 5.9.2 for a 50k-row script: medians 0.49 s vs 1.18 s (typecheck) vs 0.38 s (--transpile-only) vs 0.13 s precompiled node. TypeScript 7.0.2 crashes ts-node 10.9.2; tsx runs. Who should switch.
4 min read
On TypeScript 5.9.2, a 50,000-row script started in a median 0.49 s under tsx 4.23.15 and 1.18 s under ts-node 10.9.2 (type-checking mode). The same script under ts-node --transpile-only took 0.38 s. Precompiled node dist/script.js took 0.13 s.
Short answer: switch to tsx for day-to-day script and test runners, especially if you plan to touch TypeScript 7 — ts-node 10.9.2 crashed on TypeScript 7.0.2 in my probe (ts.sys.fileExists undefined). Keep ts-node only if you need its type-check-on-run workflow and you stay on TypeScript 5.x. No affiliate links in this post.
script.ts that builds 50,000 row objects, reduces sum/avg/max, prints one line. No network, no filesystem beyond stdout.node_modules/.bin (not npx) so installer lookup is out of the clock.TypeError: Cannot read properties of undefined (reading 'fileExists') inside its config loader.ts-node --transpile-only (0.38 s) beat tsx (0.49 s) on this script. Full ts-node with typecheck (1.18 s) was the slow one.| Runner | Mode | Median | Runs (ms) |
|---|---|---|---|
| tsx 4.23.15 | transpile + run | 0.49 s | 488 / 504 / 522 / 483 / 486 |
| ts-node 10.9.2 | typecheck + run | 1.18 s | 1438 / 1435 / 1111 / 1152 / 1179 |
| ts-node 10.9.2 | --transpile-only | 0.38 s | 378 / 418 / 368 / 503 / 370 |
| node (tsc output) | precompiled | 0.13 s | 139 / 148 / 134 / 127 / 124 |
tsx was about 2.4x faster than typechecking ts-node and about 1.3x slower than ts-node --transpile-only on this workload. If your ts-node habit is already --transpile-only (or SWC compiler host), do not expect a big win from swapping brands — pick based on TypeScript 7 readiness and DX instead.
Precompiled node still wins when the script is stable. Use a runner for tools, codegen, and tests you edit every minute; compile for anything that runs in CI every push without source changes. The TypeScript 7 upgrade decision is the companion post if the language version is the real question.
Not in my probe. With TypeScript 7.0.2 installed next to ts-node 10.9.2, ts-node script.ts died while reading config (ts.sys was undefined). The same folder with tsx 4.23.15 ran the script and printed 50000:499.50:999. Treat that as a blocker for any "upgrade TypeScript first, keep ts-node" plan until upstream catches up.
For test runners the adjacent decisions on this site are Vitest 5: should you upgrade and jsdom vs happy-dom under Vitest. Those measure the test host; this post measures how you launch the TypeScript file itself.
| Situation | My pick |
|---|---|
| Scripts and Vitest/Jest setup files on TypeScript 5.x | Prefer tsx; simpler default |
| About to move to TypeScript 7 | Prefer tsx; re-check ts-node before you rely on it |
You already use ts-node --transpile-only and stay on TS 5 | Optional; speed is close |
| You want type errors to fail the script on every run | Stay on typechecking ts-node (TS 5 only), or run tsc --noEmit in CI |
| Production long-running service | Compile with tsc (or your bundler); do not ship a TS runner |
Bottom line: on a 50k-row script, tsx started in 0.49 s versus 1.18 s for typechecking ts-node, and TypeScript 7.0.2 crashed ts-node while tsx ran. Who should not switch yet: teams that need on-run typechecking and are pinned to TypeScript 5. Everyone else can take tsx for scripts and keep tsc for the compile gate.
How this was made: I wrote the script, ran every cold start on the ShopperCove test box, probed TypeScript 7 in a separate folder, and kept the timing JSON; the write-up was drafted with AI help and checked against that output.
Lab evidence
Hands-on on ShopperCove box 5 Oct 2026 ~22:50-23:00 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 20.19.2). Script: 50000-row summarize TypeScript file. Primary versions: TypeScript 5.9.2, tsx 4.23.15, ts-node 10.9.2; invoked via node_modules/.bin. Wall medians (5 interleaved cold starts after warmup): tsx 487.734 ms (488/504/522/483/486); ts-node typecheck 1178.916 ms (1438/1435/1111/1152/1179); ts-node --transpile-only 378.312 ms (378/418/368/503/370); node dist/script.js 134.142 ms (139/148/134/127/124). TS7 probe: TypeScript 7.0.2 + ts-node 10.9.2 threw TypeError reading ts.sys.fileExists; tsx 4.23.15 on the same folder printed 50000:499.50:999. Raw: /workspace/bench-tsrun/res-tsrun.json. Not tested: ESM-only, path aliases, project references, watch mode, Windows/macOS, bun runner. No affiliate.
Both cut a string at a separator, but they fail in different ways. We ran them on Python 3.13.5 to show where partition() is safer and where split() is the right tool.
Summary2 Nov 20263 min read
What changes when you swap sort() for toSorted(), with a real 1-million-item Node.js benchmark and the support table.
Summary1 Nov 20263 min read
Dragging videos is the official way to change a playlist's order. Here are the steps from YouTube Help, where to find them in YouTube Studio, and the cases where reordering will not work.
Summary31 Oct 20263 min read