Running and Reloading with tsx

Native stripping covers most projects. When it does not — a shared module that uses enums, a tsconfig.json full of paths aliases, or .tsx files shared with a front end — the Node documentation names one replacement: tsx 12,162 (github.com/privatenumber/tsx (https://github.com/privatenumber/tsx 12,162 ), MIT, 12.1k stars). Its only runtime dependency is esbuild 126 , which compiles rather than strips. Install with npm 2,036 i -D tsx, then run npx tsx src/server.ts or node --import=tsx src/server.ts.

That second form matters: --import=tsx registers tsx as a module customization hook (Module Customization Hooks) inside a normal node process, so every other Node flag — --inspect, --env-file, --max-old-space-size — keeps working as it does for JavaScript.

tsx watch restarts on every save and knows the import graph, so editing a module restarts the entry point that depends on it:

Output of 111
$ npx tsx watch --clear-screen=false src/tick.ts
first 11:54:05
7:54:08 PM [tsx] change in ./src\tick.ts Rerunning...
second 11:54:08

Node's own --watch (Watch Mode and Scripts) does the same for stripped files and costs no dependency, so reach for tsx watch only when you already need tsx for its compilation.

Choosing a way to execute TypeScript during development
node app.ts tsx app.ts ts-node 13,120
Enums, decorators, .tsx No Yes Yes
tsconfig.json paths Ignored Honored Honored
Type checking No No Optional, slow
Direct dependencies 0 1 (esbuild) 13

ts-node is the tool every older tutorial reaches for. It still works, but 10.9.2 was published in December 2023 and nothing has shipped since, it type-checks by default (which is why it feels slow), and it pulls in thirteen direct dependencies. And tsx does not check types either, so a project that runs perfectly under tsx can still be full of type errors.