Skip to main content

The State of TypeScript Tooling in 2026

·PkgPulse Team

TL;DR

TypeScript won. Now it's about how fast you can run it. TypeScript adoption crossed 75% of active npm packages in 2025. The 2026 tooling story is about speed: tsc is slow, and the ecosystem replaced it for everything except type checking. esbuild and SWC transpile TS in milliseconds. Biome (~2M downloads) replaced ESLint + Prettier for many teams. tsx (~4M downloads) runs TypeScript files directly without config. The focus shifted from "should I use TypeScript" to "how do I make my TS workflow fast."

Key Takeaways

  • TypeScript: ~50M weekly downloads — 75%+ npm package adoption, de facto standard
  • tsx: ~4M downloads — run .ts files directly, replaces ts-node for most uses
  • ts-node: ~8M downloads — original TS runner, slower than tsx/esbuild
  • Biome: ~2M downloads — Rust linter + formatter, replaces ESLint + Prettier
  • tsc — used ONLY for type checking (--noEmit); transpilation outsourced to esbuild/SWC

TypeScript Adoption Data

npm packages shipping TypeScript types (2026):
- Built-in types (.d.ts in package): ~55% of top 1000 packages
- DefinitelyTyped (@types/): ~20% covered
- No types: ~25% (mostly old/unmaintained packages)

New package creation with TypeScript:
- 2020: ~30% TypeScript
- 2022: ~55% TypeScript
- 2024: ~70% TypeScript
- 2026: ~82% TypeScript

TypeScript in project configs (Stack Overflow 2025 survey):
- 78% of professional JS developers use TypeScript
- Up from 69% in 2023

Running TypeScript in 2026

tsx (The Modern ts-node)

# tsx — run TypeScript files directly (no config needed)
npm install -g tsx

# Run a TypeScript file
tsx scripts/seed-db.ts
tsx src/cli.ts --arg value

# Watch mode (like nodemon for TS)
tsx watch src/server.ts

# Environment variable (used in package.json)
# "scripts": { "dev": "tsx watch src/index.ts" }
// tsx — no tsconfig needed for basic use
// scripts/seed.ts
import { db } from '../src/db';
import { users } from '../src/schema';

await db.insert(users).values([
  { name: 'Alice', email: 'alice@example.com' },
  { name: 'Bob', email: 'bob@example.com' },
]);

console.log('✓ Database seeded');
process.exit(0);

// Run: tsx scripts/seed.ts
// No compilation step, no ts-node config, no esm flags
// package.json — common tsx patterns
{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "start": "node dist/index.js",  // Production: still compile first
    "build": "tsc --noEmit && tsc -p tsconfig.build.json",
    "seed": "tsx scripts/seed.ts",
    "migrate": "tsx scripts/migrate.ts"
  }
}

ts-node (Legacy but Still Used)

# ts-node — original TypeScript runner, slower
npm install -g ts-node

# ESM mode (needed for modern packages)
ts-node --esm src/index.ts

# With tsconfig
ts-node -P tsconfig.scripts.json scripts/seed.ts

# Common issue: CJS vs ESM conflicts
# tsx handles this automatically; ts-node requires flags

Why tsx over ts-node: tsx uses esbuild under the hood (no type checking, just transforms). ts-node can optionally type-check but is 5-10x slower. For scripts and dev servers, tsx is the clear choice.


Type Checking Workflow

# The 2026 TypeScript workflow:
# 1. ts-node/tsx for execution (fast, no type checking)
# 2. tsc --noEmit for type checking (separate step)

# tsconfig.json — type checking config
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",           // For Node.js ESM
    "moduleResolution": "NodeNext",
    "strict": true,                 // All strict checks enabled
    "noUncheckedIndexedAccess": true, // arr[0] is T | undefined
    "exactOptionalPropertyTypes": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "skipLibCheck": true,           // Don't check .d.ts files (faster)
    "noEmit": true                  // Type check only, don't output
  }
}

# CI pipeline
npm run build       # Uses esbuild/tsup to transpile
npx tsc --noEmit    # Type check only — catches type errors
# tsup — build tool for publishing libraries
npx tsup src/index.ts --format cjs,esm --dts --clean

# Outputs:
# dist/index.cjs       — CommonJS
# dist/index.js        — ESM
# dist/index.d.ts      — TypeScript declarations
# dist/index.d.cts     — CTS declarations (dual-build)

# package.json exports field
{
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs",
      "types": "./dist/index.d.ts"
    }
  }
}

Biome (ESLint + Prettier Replacement)

// biome.json — replace both ESLint and Prettier
{
  "$schema": "https://biomejs.dev/schemas/1.5.0/schema.json",
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": {
        "noUnusedVariables": "warn",
        "noUnusedImports": "warn"
      },
      "style": {
        "useConst": "error",
        "noVar": "error"
      },
      "suspicious": {
        "noConsoleLog": "warn"
      }
    }
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "trailingCommas": "all",
      "semicolons": "always"
    }
  },
  "files": {
    "ignore": ["node_modules", "dist", ".next", "build"]
  }
}
# Biome commands
npx biome check src/        # Lint + format check
npx biome format src/       # Format only
npx biome lint src/         # Lint only
npx biome check --write src/ # Fix auto-fixable issues

# Speed comparison on 500 TypeScript files:
# Biome:   ~80ms
# ESLint:  ~8,000ms
# Prettier: ~1,500ms
# ESLint + Prettier: ~9,500ms

Why teams switch to Biome: One config file, 100x faster than ESLint+Prettier combined, zero npm dependency hell. Trade-off: fewer rules than ESLint (especially for framework-specific rules like eslint-plugin-react-hooks).


TypeScript Config Patterns

// tsconfig.json — 2026 opinionated baseline
{
  "compilerOptions": {
    // Modern targets
    "target": "ES2022",
    "lib": ["ES2022", "DOM", "DOM.Iterable"],

    // Module system
    "module": "ESNext",
    "moduleResolution": "Bundler",  // Best for Vite/esbuild

    // Strict mode (all of these, please)
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "exactOptionalPropertyTypes": true,

    // Quality of life
    "skipLibCheck": true,
    "noEmit": true,        // Let bundler emit
    "paths": {
      "@/*": ["./src/*"]   // Path aliases
    }
  },
  "include": ["src", "tests"],
  "exclude": ["node_modules", "dist"]
}

The TypeScript Toolchain in 2026

Development:
  tsx watch server.ts          ← Run TypeScript directly

Type Checking:
  tsc --noEmit                 ← Only for types, no output

Library Publishing:
  tsup / unbuild               ← CJS + ESM + .d.ts in one command

Application Bundling:
  Vite / Turbopack / esbuild  ← Transpile + bundle (no type check)

Linting + Formatting:
  Biome (all-in-one)
  OR ESLint + Prettier (more rules but 100x slower)

Testing:
  Vitest                       ← Native TypeScript support via Vite

When to Choose Each Tool

ToolUse Case
tsxRun scripts, dev servers, one-off utilities
ts-nodeLegacy codebases, when tsx has compatibility issues
tscType checking only (--noEmit in CI)
tsupPublishing npm packages with CJS/ESM dual output
BiomeFast lint+format, TypeScript-heavy projects
ESLintWhen framework plugins are essential (React hooks, etc.)
esbuildBundling in CI, custom build pipelines

Compare TypeScript tooling package health on PkgPulse.

Comments

Stay Updated

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