Skip to main content

tsx vs ts-node vs esno: Running TypeScript Directly in Node.js (2026)

·PkgPulse Team

TL;DR

tsx (TypeScript Execute) is the modern winner in 2026 — powered by esbuild, starts in milliseconds, full ESM support, replaces node drop-in, and works with node --import tsx for seamless Node.js integration. ts-node is the original TypeScript runner — slower (uses TypeScript compiler, not esbuild), but has the most complete TypeScript feature support including paths aliasing, decorators, and experimental features. esno is tsx under the hood (same esbuild-based approach, by the same author). In 2026: use tsx for development scripts and tooling; use a full build step (tsc, tsup, Vite) for production.

Key Takeaways

  • tsx: ~8M weekly downloads — esbuild-powered, instant startup, ESM + CJS, node --import tsx syntax
  • ts-node: ~15M weekly downloads — TypeScript compiler, slower but full TS feature parity
  • esno: ~1M weekly downloads — thin wrapper around tsx (same engine), being superseded by tsx
  • tsx transpiles with esbuild, skipping type-checking — 100x faster than ts-node
  • ts-node is the only option for full TypeScript diagnostics at runtime (via typeCheck: true)
  • Node.js 22.6+ has experimental native TypeScript stripping — the future is built-in

The Problem: TypeScript in Scripts and Dev Tools

// Problem: Node.js doesn't natively run .ts files
// node src/migrate.ts → SyntaxError: Unexpected token ':'

// Solution: a TypeScript runner transpiles on the fly:
// tsx src/migrate.ts    → runs instantly (esbuild)
// ts-node src/migrate.ts → runs (TypeScript compiler, slower)

// Use cases:
//   - Database migration scripts
//   - CLI tools
//   - Development scripts (seeding, fixtures)
//   - Testing (vitest, jest with ts-jest)
//   - Build scripts that aren't worth compiling
//   - Rapid prototyping

tsx

tsx — esbuild-powered TypeScript runner:

Basic usage

# Install:
npm install -D tsx

# Run a TypeScript file:
npx tsx src/index.ts
npx tsx src/scripts/migrate.ts

# Pass arguments:
npx tsx src/scripts/seed.ts --env staging

# Watch mode (re-run on file changes):
npx tsx watch src/index.ts

Drop-in replacement for node

# Use tsx as a node replacement:
tsx src/index.ts

# Works with node flags:
tsx --env-file=.env src/index.ts
node --import tsx src/index.ts   # Preferred for Node.js 18+

package.json scripts

{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "migrate": "tsx src/db/migrate.ts",
    "seed": "tsx src/db/seed.ts",
    "generate": "tsx scripts/generate-types.ts"
  },
  "devDependencies": {
    "tsx": "^4.0.0"
  }
}
# Register tsx as a loader — allows require/import of .ts files:
node --import tsx/esm src/index.ts         # ESM mode
node --require tsx/cjs src/index.ts        # CJS mode

# In package.json:
{
  "scripts": {
    "start:dev": "node --import tsx src/index.ts"
  }
}

With Vitest and Jest

// vitest.config.ts — tsx handles TypeScript for vitest natively:
import { defineConfig } from "vitest/config"

export default defineConfig({
  test: {
    // Vitest already uses Vite/esbuild — no tsx needed for tests
  },
})

// jest.config.ts — use tsx as transformer:
export default {
  transform: {
    "^.+\\.tsx?$": [
      "ts-jest",
      { useESM: true },
    ],
    // Or use tsx with jest directly via @jest/globals
  },
}

tsconfig compatibility

// tsx reads your tsconfig.json automatically:
// compilerOptions.paths → resolved (via esbuild's tsconfig-paths)
// compilerOptions.target → respected
// compilerOptions.moduleResolution → bundler mode
// decorators → supported via esbuild

// tsx does NOT run type checking (it's a transpiler, not type checker)
// Run type checking separately:
// tsc --noEmit

What tsx does NOT support

# tsx strips types — it does NOT:
#   - Report type errors
#   - Support experimental features not in esbuild (const enums across files)
#   - Support all tsconfig.json paths configurations equally

# For production with full tsc features, use tsc or tsup to build:
npx tsc --noEmit    # Type check only (no output)
npx tsup src/index.ts  # Build with full TS + bundle

ts-node

ts-node — the original TypeScript Node.js runner:

Basic usage

# Install:
npm install -D ts-node typescript

# Run:
npx ts-node src/index.ts

# REPL:
npx ts-node

tsconfig.json for ts-node

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "CommonJS",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "ts-node": {
    "swc": true,          // Use SWC for transpilation (much faster!)
    "esm": false,         // Enable ESM (requires Node.js 12+)
    "experimentalSpecifierResolution": "node"
  }
}

SWC mode (fast ts-node)

# ts-node with SWC transpiler (similar speed to tsx):
npm install -D ts-node @swc/core @swc/helpers

# In tsconfig.json:
# "ts-node": { "swc": true }

npx ts-node --swc src/index.ts
# Or with the config above, just:
npx ts-node src/index.ts

ESM mode

# ts-node ESM mode requires:
# 1. tsconfig.json: { "compilerOptions": { "module": "ESNext" } }
# 2. package.json: { "type": "module" }

npx ts-node --esm src/index.ts

# Or use node with loader:
node --loader ts-node/esm src/index.ts

Full type checking at runtime

// ts-node with type checking enabled (slow but catches type errors):
// tsconfig.json:
{
  "ts-node": {
    "typeCheck": true   // Default: false. Enables full diagnostics.
  }
}

// CLI:
// ts-node --type-check src/index.ts

// Use case: CI validation scripts where type errors should halt execution
// Not recommended for dev iteration — too slow

ts-node vs tsx performance

Cold start (simple script):
  ts-node (default):    ~2000ms (TypeScript compiler)
  ts-node (swc: true):  ~200ms (SWC transpiler)
  tsx:                  ~100ms (esbuild)
  esno:                 ~100ms (same as tsx)
  Bun (built-in TS):    ~50ms (no tool needed)

For 100-file project:
  ts-node: noticeably slower on each run
  tsx: still fast — esbuild is extremely efficient

esno

esno — thin esbuild-based runner:

# esno is a thin wrapper around tsx with a slightly different CLI:
npm install -D esno

# ESM mode:
npx esno src/index.ts

# CJS mode:
npx esno/esno src/index.ts  # or: npx cjs-esno src/index.ts
// esno is now just an alias for tsx from the same author
// The author (antfu) recommends using tsx directly in new projects:
// "esno is essentially the same as tsx now"

// If you see esno in older projects, it can be replaced with tsx:
// npm uninstall esno && npm install -D tsx
// Replace "esno" with "tsx" in package.json scripts

Feature Comparison

Featuretsxts-nodeesno
TranspileresbuildTypeScript (or SWC)esbuild
Cold start⚡ ~100ms🐌 ~2000ms (or ~200ms with SWC)⚡ ~100ms
Type checking✅ (optional)
ESM support✅ Full✅ (with config)✅ Full
CJS support
Watch mode
tsconfig paths
Decorators✅ (esbuild)✅ (TS compiler)
const enum across files
Bun alternativebun runN/AN/A
Weekly downloads~8M~15M~1M

When to Use Each

Choose tsx if:

  • Running TypeScript scripts, CLIs, and dev tooling (the default choice in 2026)
  • Need fast startup for scripts that run frequently
  • Full ESM support with node --import tsx
  • Drizzle migrations, Prisma seed files, custom build scripts

Choose ts-node if:

  • You need runtime type checking (typeCheck: true)
  • Using TypeScript features esbuild doesn't fully support (complex const enum across files)
  • Legacy project already on ts-node — no reason to migrate unless performance is a problem
  • Need maximum tsconfig.json compatibility

Choose esno if:

  • Inherited a project using esno — it works fine, consider migrating to tsx

Use Bun instead if:

  • Already running Bun — it runs TypeScript natively with zero configuration (bun run src/index.ts)

For production builds — don't use any of these:

# Always build for production with a real compiler:
npx tsc --outDir dist       # Full TypeScript compiler
npx tsup src/index.ts       # esbuild with TypeScript, bundles + dts
npx tsdown src/index.ts     # Rolldown-based, faster tsup alternative

Methodology

Download data from npm registry (weekly average, February 2026). Feature comparison based on tsx v4.x, ts-node v10.x, and esno v0.x.

Compare TypeScript tooling and developer experience packages on PkgPulse →

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.