Skip to content

Instantly share code, notes, and snippets.

@ggemre
Last active February 27, 2025 15:06
Show Gist options
  • Save ggemre/83219067c5fc0623e92e086e45fe4e8e to your computer and use it in GitHub Desktop.
Save ggemre/83219067c5fc0623e92e086e45fe4e8e to your computer and use it in GitHub Desktop.
Migrating from ts-node to tsx

Switching from ts-node to tsx

Important Resources:

Main Comparison

The tsx documentation includes the following points about what makes it a better option than ts-node:

  • tsx is zero-config because it has smart detections built in. As a runtime, it detects what's imported to make many options in tsconfig.json redundant—which was designed for compiling matching files regardless of whether they're imported.
  • It seamlessly adapts between CommonJS and ESM package types by detecting how modules are loaded (require() or import) to determine how to compile them. It even adds support for require()ing ESM modules from CommonJS so you don't have to worry about your dependencies as the ecosystem migrates to ESM.
  • At the core, tsx is powered by esbuild for blazing fast TypeScript compilation, whereas ts-node (by default) uses the TypeScript compiler.

Important functionality differences:

  • ts-node incorporates type checking, tsx does not
  • tsx handles package types automatically, ts-node does not
Our usage of ts-node tsx equivalent Description
node -r ts-node/register node --import tsx We use node directly to run .ts files by registering/importing a ts interpreter. (See NOTE below).
nyc mocha -r ts-node/register nyc mocha --import tsx Used for testing typescript projects.

Note

node --import tsx adds support for both Module and CommonJS contexts. To only import one, you can use node --import tsx/esm or node --require tsx/cjs.

node -r ts-node/register only supports a CommonJS context, node --loader ts-node/esm must be used for projects that are type Module.

Developer Experience

On average tsx was faster, (about twice as fast on medium sized projects), than ts-node. tsx also includes a watch option which automatically reruns when the codebase is changed, which can be useful in certain circumstances. Overall, it feels that losing type checking for a faster and more flexible runtime is a better choice for OIT's usage, (mainly running tests and small dev scripts as far as I can tell).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment