Back Original

A Small Year for tsc, a Giant Year for TypeScript

In terms of new TypeScript features, 2025 was a very quiet year. But it's been a big year for TypeScript and typed JavaScript in general, and the ecosystem has a new direction that sets the stage for big fireworks in 2026.

The two big announcements in 2025 were:

  1. Microsoft is rewriting the TypeScript compiler and language service in Go.
  2. Node.js began supporting TypeScript natively.

TypeScript rewrite in Go

I've followed the TypeScript release notes for years. Recent releases have had relatively few big new language features, and many of these have been contributed by external developers. This March, we found out why: The TypeScript team at Microsoft has been working on a massive project to port tsc and tsserver from TypeScript to Go.

My first reaction was: "is it April 1st already?" My next reaction was a whole lot of mixed feelings.

It's generally considered a good practice for compilers to be bootstrapped, i.e. written in their own language. While this sounds strange at first, it's quite common and has several positive consequences:

  1. It's a demonstration that you can build a large, substantial program in the language.
  2. It makes the development team aware of issues in the language, since they work in it day-to-day.
  3. It makes the development team acutely sensitive to compiler and language service performance.

No one doubts that you can build large programs in TypeScript, but the "dogfooding" aspect of self-hosting has been good for the TypeScript ecosystem. Every TypeScript release comes with performance improvements, and one reason for this is that the TS team appreciates fast builds and responsive editors, too.

So bootstrapping is, in principle, good. That being said, a 10x speedup should make you question your principles.

When I was developing my inferred type predicates feature, I was struck that the TypeScript in tsc is written in a distinctive, low-level style. It often looks more like C than JavaScript. I started to think about how you could turn that into a faster tsc. A direct port to C wouldn't work since JavaScript has garbage collection and tsc relies on that. I wrote in a notebook: "what's the lowest-level language with garbage collection?" I figured it might be Java and left things there.

It seems the TS team, in particular Jake Bailey, went through the same thought process and came to a different conclusion: Go!

The new TypeScript is a line-by-line port of the existing one. There's a notorious 50,000+ line checker.ts file today, and in the future there will be a 50,000+ line checker.go. TypeScript 6.0 will be the last TypeScript-based version of TypeScript, and then future versions will be written in Go.

The upshot is that, sometime next year, you'll update your packages and everything will get 10x faster. Slow compiler and language service performance has always been one of the biggest complaints about TypeScript. I've experienced this myself on large projects and I'm looking forward to the speed boost.

My other hope is that, once the dust settles, we'll see a renewed focus on new language features.

Node.js Runs TypeScript Natively

This one flew under the radar for me when it happened earlier this year, and perhaps it's news to you, too: Node.js now natively supports TypeScript!

> node test.ts

Impressive stuff! This should work with any version of Node.js after 22.18.0, which was released on July 31st, 2025. (This behavior has been available since Node 22.6.0 last year via --experimental-strip-types.)

This is a big deal. Ever since Node came out in 2009, people have been running preprocessors in front of it to improve JavaScript in various ways. CoffeeScript was one of the first, then we started using "transpilers" like Babel to get early access to ES2015 features, and now we use TypeScript to get types. In all these cases, we're adding a tool to the stack. It has to be configured, you have to know it exists, and something might go wrong with it. In short, it adds friction.

Node.js has supported ES2015 features for years now, so there's no need for a transpiler to use arrow functions, async, Map, etc. Now you don't need tsc to use TypeScript with node. It just works out of the box.

A few things to note here:

  1. This is only about running your code. Node doesn't do type checking. It simply strips off the types. If you want type checking (and you do!) then you'll still need to run tsc separately.
  2. Since this works by stripping types, you can't use TypeScript's niche runtime features: enums, parameter properties, triple-slash imports, experimental decorators, and member visibility modifiers (private). I've long advised against doing this (See Effective TypeScript Item 72: Prefer ECMAScript Features to TypeScript Features) and, as of TypeScript 5.8, there's an --erasableSyntaxOnly flag to keep you away from these.
  3. Stripping types doesn't change line numbers, so you don't need source maps to debug.
  4. While TypeScript supports any TC39 proposal at stage 3 or later, Node.js only supports features once they've landed in the spec. So for the few features in between those states, you'll need to hold off until they're official.

I want to reiterate that this doesn't do any type checking! Node will happily run programs with clear type errors:

> node test-bad.ts

tsc can strip type annotations, of course, but there are several other tools that do the same thing, like Bloomberg's aptly-named ts-blank-space. Node uses @swc/wasm-typescript, which uses WASM for speed.

So does this mean that TypeScript has won? On some level, yes. It's so widely adopted now that Node.js felt the need to add built-in support. But this change also opens the door to more competition in the typed JavaScript landscape. It was designed with TypeScript in mind, but it doesn't have to be tsc checking your code. It could be some other type checker instead.

This puts JavaScript in a situation akin to Python. Python has a standardized syntax for type annotations but, for the most part, they have no effect on the runtime behavior of your program. There's a healthy ecosystem of type checkers for Python that all use the same syntax for type hints, but have different philosophies and provide different sorts of checking. Examples of Python type checkers include mypy, pyright (Microsoft), pyrefly (Facebook) and ty (Astral).

By standardizing a syntax for type annotations, Node is making it easier for new entrants to bring their own take on type checking to JavaScript. Competition is a good thing, and I hope this brings some of it to the typed JavaScript ecosystem.

What about browsers? There's a Microsoft-backed TC39 proposal to add type annotations to the language itself, but it's only at stage 1. I assume it would need to advance significantly before there's browser adoption. I hope Node's move gives this proposal some momentum. As it says, the motivation is to "unfork JavaScript," which would be good for everyone.

So long 2025! Here's hoping that 2026 brings faster build times, more responsive editors, exciting new language features, and a simpler JavaScript ecosystem.