DEV Community

Cover image for TypeScript 7 Went Native: What Actually Changes And What Doesn't
Nazar Boyko
Nazar Boyko

Posted on

TypeScript 7 Went Native: What Actually Changes And What Doesn't

Rewritten in Go for massive performance gains

Everyone's heard by now that TypeScript "went native." And I keep seeing the same wrong conclusion drawn from it: that TypeScript now somehow runs without being compiled, that the build step is gone, that your .ts files execute directly.

None of that happened. Your browser still can't run TypeScript. Node still can't type-check it. The thing that went native isn't your code. It's the compiler.

And honestly, that's the better story.

What "Native" Actually Means

For its entire life the TypeScript compiler has been written in TypeScript. tsc, the thing you run in CI and tsserver the thing feeding your editor its red squiggles were JavaScript programs executing on Node.js. Every type-check of your million-line codebase was itself a JavaScript program churning through a pointer-heavy graph of type objects, single-threaded with JIT warmup and garbage-collector pressure along for the ride.

TypeScript 7 replaces that with a compiler written in Go, compiled ahead of time to a native binary. Microsoft announced the port in March 2025 with Anders Hejlsberg TypeScript's lead architect fronting the effort and shipped it as TypeScript 7.0 on July 8, 2026.

So when you read "native TypeScript," expand it to "natively compiled TypeScript toolchain." The pipeline looks like this:

  • Before: your .ts files go into a compiler written in JS, running on Node, and out come type errors plus emitted .js.
  • After: your .ts files go into a compiler that's a native Go binary, and out come the same type errors plus the same emitted .js.

The first box and the last box didn't change. Only the middle one did. That's the whole announcement and it's enough to be a big deal.

Comparison diagram titled What Actually Went Native: TypeScript 6 pipeline with tsc as JavaScript on Node.js versus TypeScript 7 pipeline with tsc as a native multi-threaded Go binary, input and output boxes unchanged

Where The 10x Comes From

The headline number holds up. These are Microsoft's published full-build benchmarks from the 7.0 release post:

Codebase TypeScript 6 TypeScript 7 Speedup
VS Code 125.7s 10.6s 11.9x
Sentry 139.8s 15.7s 8.9x
Playwright 12.8s 1.47s 8.7x

The original announcement benchmarks told the same story on type-checking alone: VS Code's 1.5 million lines went from 77.8s to 7.5s, TypeORM from 17.5s to 1.3s, tRPC from 5.5s to 0.6s. The multiplier is remarkably consistent across project sizes which tells you it's not some cache trick that only helps huge repos. It's the floor moving.

Here's the part most coverage skips: native compilation alone doesn't buy you 10x. Going from JIT-compiled JavaScript to ahead-of-time Go gets you a chunk of it. The rest comes from shared-memory multithreading, something the old compiler structurally couldn't do. JavaScript's worker threads can't share object graphs; they pass messages and copy data. A type-checker whose entire job is traversing one giant shared graph of types was stuck on a single core. In Go the checker splits work across parallel workers that all read the same memory.

TypeScript 7 exposes this directly. Type-checking runs on 4 workers by default, and you can turn the dial:

# default: 4 type-checking workers
npx tsc -p tsconfig.json

# crank it up on a beefy CI box
npx tsc -p tsconfig.json --checkers 8
Enter fullscreen mode Exit fullscreen mode

With --checkers 8, Microsoft's VS Code benchmark drops to 7.51s, a 16.7x speedup over TypeScript 6. That's the compounding effect: native code made the work faster, and concurrency made the work parallel.

Memory moved in the right direction too: the 7.0 post reports aggregate build memory down 18% on VS Code and 26% on Bluesky's codebase. Not headline material next to 10x but if you've ever watched tsc eat 4GB in CI, you'll take it.

What Changes In Your Day

Numbers on Microsoft's benchmark machines are nice. What matters is where the time comes back in your week. It shows up in three places.

The editor. This is the one you'll feel first, because you feel it hundreds of times a day. Project load in the original benchmarks went from 9.6 seconds to 1.2 seconds on VS Code's codebase. The 7.0 release measured opening a file with errors dropping from 17.5 seconds to under 1.3. If you've worked in a large monorepo you know the ritual: open a file, wait, watch "Initializing JS/TS language features" spin, go get coffee, come back to squiggles. That ritual is what dies here. The language service was also rebuilt on the Language Server Protocol and Microsoft reports over 80% fewer failing commands and over 60% fewer crashes than the 6.0 server. Fewer "restart TS server" moments is its own quality-of-life feature.

CI. The typecheck step has been the quiet bottleneck of a lot of pipelines: too important to skip, too slow to love. The release post has real production numbers here. Slack cut CI type-checking from 7.5 minutes to 1.25 and eliminated 40% of their merge queue time. Canva's error detection went from 58 seconds to 4.8. Microsoft's own News Services team reports around 400 hours a month no longer spent waiting on CI builds. When the typecheck stops being the long pole, merge queues drain faster and "just rerun CI" stops costing you a coffee break.

The workarounds you stop needing. This one's subtle and, I think, the most interesting. A slow compiler doesn't just cost time. It bends architecture. skipLibCheck: true is in half the tsconfigs on GitHub not because anyone wanted less checking but because checking node_modules types was too expensive. Project references with their composite builds and .tsbuildinfo choreography, exist substantially as a performance escape hatch and plenty of monorepos were split along lines chosen to keep tsc bearable rather than lines that made sense for the domain. When the full check of a 1.5M-line codebase takes 10 seconds the pressure behind all of that eases. You don't have to un-do your project references tomorrow. You just stop reaching for the gymnastics the next time and that changes how codebases grow from here.

What Doesn't Change

Now the myth-busting half of the ledger, because this list is exactly as important:

  • Your emitted JavaScript. Same input, same output. The build artifact your users download doesn't change by a byte's worth of behavior.
  • Your runtime. Nothing about how your code executes is different. This is a compile-time story, full stop.
  • The type system's rules. TypeScript 7 is built to match TypeScript 6.0's type-checking behavior. Code that compiled cleanly on 6.0 should compile identically on 7.0. Your types didn't get stricter, looser, or smarter. They got checked faster.

This wasn't luck. It's the reason the team chose Go in the first place. The existing compiler is a decade of accumulated behavior: pointer-heavy tree traversals, shared mutable state, thousands of subtle decisions encoded in its structure. The team explicitly framed the project as a port, not a rewrite, translating the existing codebase nearly function-for-function to preserve its exact behavior. Go won because idiomatic Go could mirror the existing code's shape; a Rust version would've forced them to rethink memory and mutation from scratch, turning a port into a rewrite and a compatibility promise into a prayer.

I'd call that the most underrated engineering decision in the whole project. The boring choice, the one that let them prove behavior stayed identical, is the reason you can adopt a compiler rewrite with roughly the same risk profile as a minor version bump.

This Is Not Node's Type Stripping

People keep conflating these two, and they're solving opposite problems.

Since Node 22.6.0, and enabled by default from 23.6.0 onward, Node can run TypeScript files directly by stripping the types out. And "stripping" is delightfully literal: Node replaces your type annotations with whitespace and executes what's left, so line and column numbers still match your source. No type-checking happens. None. You can declare const port: number = "definitely not a number" and Node will run it without a complaint.

That's also why only erasable syntax works, meaning anything you can delete without changing runtime behavior:

// runs fine under Node's type stripping:
interface User {
  id: number;
  name: string;
}
const greet = (user: User): string => `Hi, ${user.name}`;

// throws ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX, because an enum
// is not erasable: it generates real runtime code
enum Role {
  Admin,
  Member,
}
Enter fullscreen mode Exit fullscreen mode

Enums, namespaces with runtime code, and constructor parameter properties all generate JavaScript, so deleting them would change behavior, so Node's default mode refuses them.

So the line between the two:

  • Node's type stripping answers "can I run this .ts file without a build step?" It executes your code and checks nothing.
  • The native TypeScript compiler answers "can I check this code before it ships?" It validates everything and got 10x faster at it.

They're complementary, not competing. A perfectly modern setup in 2026 is Node executing your .ts files directly in development while the native tsc runs the actual type-check in your editor and CI. One removes a build step; the other makes the safety net fast enough that you never think about it.

Timeline And Migration, Honestly

Where things stand as of mid-2026:

TypeScript 7.0 is GA. It's the typescript package on npm, and the binary is still called tsc. If you played with the preview, that was @typescript/native-preview with a tsgo binary; that era is over, and the native compiler is now just... TypeScript.

The 6.x line continues. The JavaScript-based compiler lives on as TypeScript 6, maintained in parallel until the native port fully takes over. There's even a compatibility package that installs it as tsc6 alongside 7, which matters because of the next point.

The programmatic API is the honest asterisk. TypeScript 7 doesn't yet expose a stable API for tools that consume the compiler as a library. That means typescript-eslint's type-aware rules, and the template type-checking behind Vue, Svelte, and Astro, still need TypeScript 6 under the hood. The stable API is slated for 7.1. Until then, tooling-heavy setups run both:

package.json

{
  "devDependencies": {
    "typescript": "npm:@typescript/typescript6@^6.0.2",
    "@typescript/native": "npm:typescript@^7.0.2"
  }
}
Enter fullscreen mode Exit fullscreen mode

Your fast builds and editor experience come from 7; your lint toolchain keeps the 6 API it needs. Clunky, temporary, and worth it.

Some defaults tightened. 7.0 flips strict on by default, defaults module to esnext, and drops long-deprecated targets like ES5 and AMD/UMD output. If your tsconfig already says what it means, and it should, you'll barely notice. If you're on a codebase that never turned strict on, the compiler didn't break your code; it just stopped pretending the old defaults were fine.

Note
If you maintain a plain tsc-built project, the upgrade is about as boring as upgrades get: bump the package, run the build, read the handful of config warnings. The teams that should wait a beat are the ones whose toolchain reaches into the compiler API. Check your lint setup and framework tooling before flipping the switch.

A Tooling Story, Not A Language Story

TypeScript 7 adds nothing to the language and that's precisely why it matters. Every previous major version gave you new type-system toys. This one gives you back the time you've been quietly paying at every keystroke, every save, every push and it retires a whole category of architectural decisions that were never really architecture just coping mechanisms for a slow compiler.

The 10x makes headlines. Watching what large TypeScript teams stop doing because of it will be the real payoff.


P.S. Thanks for taking the time to read this article! The ideas and opinions expressed here are my own. English is not my first language, so I use AI to help correct grammar and make my writing clearer and easier to read. If anything still sounds a little awkward, I appreciate your understanding!

Originally published at nazarboyko.com.

Enjoyed this one? Let's stay in touch β€” I'm on LinkedIn, always happy to chat, swap ideas, or just say hi. πŸ‘‹

Top comments (62)

Collapse
 
igordop profile image
Π˜Π³ΠΎΡ€ΡŒ

At the moment it feels like nothing really changed for most developers besides the performance improvements. But changing the compiler core is a huge step. I think the real impact will come in future releases because this new foundation should make it much easier to introduce bigger features and optimizations without being limited by the old architecture.

Collapse
 
nazar-boyko profile image
Nazar Boyko

Agreed, the foundation is the real story here. The old compiler was locked to a single thread by JavaScript itself, so a whole class of optimizations was off the table no matter how clever the code got. Now that the checker already scales across parallel workers, I would expect future releases to push much further on incremental builds and editor performance than the old architecture ever allowed.

Collapse
 
igordop profile image
Π˜Π³ΠΎΡ€ΡŒ

Good point. Which area do you think will benefit the most, incremental builds or editor responsiveness?Do you think we'll start seeing those bigger improvements already in the next major release?

Thread Thread
 
nazar-boyko profile image
Nazar Boyko

My money is on editor responsiveness, simply because you feel it hundreds of times a day while a full build you feel a few times. There is also a funny side effect, when a clean full check of a huge codebase takes ten seconds, incremental state matters less than it used to. So the editor is where the parallel checker really pays off. On timing the only thing announced for 7.1 is the stable compiler API, so my guess is the bigger performance pushes come after that once the ecosystem is back on one version.

Thread Thread
 
igordop profile image
Π˜Π³ΠΎΡ€ΡŒ

Yeah, that makes sense. Faster editor feedback is something every developer notices immediately. It'll be interesting to see how much they can improve once the ecosystem catches up.

Collapse
 
ingosteinke profile image
Ingo Steinke, web developer

None of that happened. Your browser still can't run TypeScript. Node still can't type-check it.

Well said. JavaScript got new syntactical sugar every year, but it's still missing type safety. So we're still writing --C0ffeeScript-- TypeScript that needs to compile. Most devs used to transpile their vanilla JS as well, too, to use the new syntax and still provide backward compatibility.

So, TypeScript 7 didn't really chang anything from a web developers' perspective.

Collapse
 
nazar-boyko profile image
Nazar Boyko

Thanks Ingo. You are right that nothing changed in what ships to the browser,that was half the point of the article. Where I would push back a little: the feedback loop is also part of the web developer perspective and waiting for squiggles and CI is where a lot of our day actually goes. The code stayed the same but the waiting did not and I will take that trade.

Collapse
 
glenallen profile image
Glen Allen

One interesting point is that performance improvements are often most valuable when they don't require developers to change the way they work. Faster tooling with minimal migration effort tends to have a much bigger long-term impact than introducing new language features that require teams to rethink existing codebases.

Collapse
 
nazar-boyko profile image
Nazar Boyko

Well said. The zero migration part was a deliberate choice too since the team ported the old compiler almost function for function precisely so adoption would feel like a minor version bump instead of a rewrite gamble. And I think the long term impact goes beyond the saved minutes, teams quietly stop doing things like skipLibCheck everywhere or splitting repos just to keep the compiler bearable and that changes how codebases grow without anyone announcing anything.

Collapse
 
jeremy_6a02b3 profile image
Jeremy II

That is a good point. Better defaults can have a bigger impact than people expect.

Collapse
 
anabolic profile image
Anabolic

Like that you separated the real changes from the hype and made it clear that most developers will mostly notice the performance improvements, not major language changes. Do you think the ecosystem will catch up quickly, especially tools like ESLint and ts-jest? Also, have you tried TypeScript 7 on a large production project yet, and if so, did the build times improve as much as expected?

Collapse
 
nazar-boyko profile image
Nazar Boyko

Thanks! On the ecosystem question, the key date is 7.1 when the stable compiler API ships. Tools like typescript eslint and the framework template checkers need that API which is why the dual setup with TypeScript 6 exists today. My guess is the catch up will be quick after that since the big tool teams have been preparing since the preview days. As for production experience, I have not migrated a large codebase myself yet,so I am relying on the published numbers from teams like Slack and Canva and those came from real production pipelines.

Collapse
 
anabolic profile image
Anabolic

That makes sense. Waiting for the stable compiler API before migrating sounds like the safest approach. It will be interesting to see how quickly the major tooling projects adopt it after 7.1. Thanks for the detailed explanation and for clarifying where the performance numbers are coming from. I will definitely keep an eye on real world migration reports.

Thread Thread
 
nazar-boyko profile image
Nazar Boyko

Same here, the real world migration reports will be the interesting part. Thanks for the good questions!

Thread Thread
 
anabolic profile image
Anabolic

Absolutely. Benchmarks are useful, but real world projects usually reveal the edge cases. Looking forward to seeing how the first large migrations go. Thanks again, nice reading!

Thread Thread
 
nazar-boyko profile image
Nazar Boyko

Thanks!

Collapse
 
vinimabreu profile image
Vinicius Pereira

The line I keep coming back to is skipLibCheck: true. Half the tsconfigs I have inherited carry it, and nobody in the room remembers it was a performance concession. It just quietly became "how we configure TypeScript" while silently giving up real type checking at library boundaries.

That is the part of this release worth watching: the workarounds do not remove themselves. A 10x compiler means teams can afford correctness they had already stopped paying for, but only if someone goes back through the config and asks which flags were beliefs and which were just the clock. Same story with the project references people split repos over. Fast enough changes what is reasonable, and reasonable is where the cleanup has to happen deliberately.

Collapse
 
oliver_rodriguez profile image
Oliver Rodriguez

I really like the idea of treating upgrades as a chance to revisit old compromises. Sometimes a config option survives long after the original problem is gone, simply because nobody wants to touch something that works. Faster tooling changes that balance and gives us a good reason to clean things up.

Collapse
 
nazar-boyko profile image
Nazar Boyko

True, and the nobody wants to touch it fear is real. A ten second full check makes that experiment cheap enough that fear stops being a good reason.

Collapse
 
nazar-boyko profile image
Nazar Boyko

You are right that the workarounds do not remove themselves and I would add that the upgrade PR is the natural moment to do the cleanup, since that is the one time the whole team is actually looking at the tsconfig anyway. A cheap experiment is to flip skipLibCheck off right after upgrading and just measure because the answer used to be minutes and now it is often seconds, and that turns a philosophical debate into a number. Also I am absolutely stealing the line about flags that were beliefs and flags that were just the clock.

Collapse
 
vinimabreu profile image
Vinicius Pereira

Take the line, it is yours.

One practical note for when someone does flip it off after the upgrade: expect the first run to go red, and expect most of it to be duplicate or mismatched @types in the tree rather than real bugs in your code. That is worth knowing in advance because a red wall on the upgrade PR is exactly what makes a team put the flag back and never revisit it. The move that survives contact: run the strict version as a separate non-blocking CI job for a week. You get the number and the error list without holding anyone's PR hostage, and then the decision to fix or keep is made with evidence instead of at 6pm on a Friday.

The upgrade PR being the one moment everyone is already looking at the tsconfig is a very good point. It is also the only moment the diff has an audience.

Thread Thread
 
nazar-boyko profile image
Nazar Boyko

The non blocking shadow job is the right move and it generalizes to any tightening, new strict flags, new lint rules, anything where the first run goes red for reasons that are mostly noise. A week of data turns put the flag back from a reflex into a decision made with evidence. And the only moment the diff has an audience might be an even better line than the first one, so now I owe you two.

Thread Thread
 
vinimabreu profile image
Vinicius Pereira

Consider both paid, the post is what started the thought. Good writing does that, it gives people somewhere to put an idea they had been carrying around loose.

Collapse
 
xm_dev_2026 profile image
Xiao Man

The "first box and last box did not change, only the middle one" framing is the clearest way to say what actually shipped. Most people read the headline as "TypeScript is faster" when the real story is "the TypeScript toolchain is faster." Your editor experience, your CI pipeline, your type-check-on-save β€” all of those benefit from a Go binary that does not need JIT warmup or garbage collection pressure on every run.

The interesting question this raises is whether Go becomes the default language for rewriting developer toolchains. esbuild started the trend (also Go), Biome went Rust, and now tsc is Go. The pattern is the same: a hot-path tool that was written in the same language as its users gets rewritten in a language that compiles ahead of time and starts fast. The users still write TypeScript, JavaScript, or whatever β€” the tool itself becomes invisible infrastructure.

One thing worth watching: the native binary replaces tsserver, which means editor integrations that depend on the tsserver protocol need to either adapt or wrap. VS Code ships with TypeScript so Microsoft controls that path, but third-party editors and language servers may need a compatibility shim. The 10x speedup only matters if the integration layer does not add back latency through IPC overhead.

Collapse
 
nazar-boyko profile image
Nazar Boyko

Thanks, glad the framing landed. On the editor side there is actually good news: the new language service speaks the standard Language Server Protocol, and the old tsserver protocol was the custom one that needed wrappers. So third party editors like Neovim or Zed should have an easier time now, not harder. The Go vs Rust question is fun to watch too, though here Go won mainly because it let the team port the old compiler almost function for function instead of rewriting it.

Collapse
 
brandonharu profile image
Brandon Haru

The compiler rewrite is probably just the first step. If TypeScript is no longer limited by JavaScript runtime performance, we might finally see features that were previously considered too expensive for large codebases. Better type analysis could become the default instead of an opt in.

Collapse
 
brandonharu profile image
Brandon Haru

and I think, the biggest win might not be faster builds but what happens inside editors. If type checking becomes cheap enough, IDEs can provide much richer refactoring and diagnostics without developers noticing any latency.

Collapse
 
nazar-boyko profile image
Nazar Boyko

I think you are onto something, especially with the editor angle. Project wide diagnostics are a good example, today most editors only fully check the files you have open, because checking the whole project on every keystroke was unthinkable and a parallel native checker makes it thinkable. The same logic applies to defaults, since things like skipLibCheck exist purely because checking node_modules was too expensive, and that tradeoff just changed. Curious which one you would want first if the type checking budget is suddenly ten times bigger.

Collapse
 
jeremy_6a02b3 profile image
Jeremy II

Great breakdown. I like that you focused on what actually changes versus what is just marketing hype. Do you think the biggest challenge for most teams will be updating the surrounding tooling rather than migrating their TypeScript code itself?

Collapse
 
nazar-boyko profile image
Nazar Boyko

Thanks Jeremy! That is exactly how I see it. The compiler was built to match TypeScript 6 behavior, so your own code mostly just compiles faster with no migration to speak of. The real friction is in tools that consume the compiler as a library,like type aware lint rules and template checking in Vue or Svelte and that gap should close once the stable API lands in 7.1.

Collapse
 
jeremy_6a02b3 profile image
Jeremy II

Thanks for the clarification. That makes a lot of sense. Do you think most popular tools will be ready soon after 7.1, or will it take a few release cycles before the ecosystem catches up?

Thread Thread
 
nazar-boyko profile image
Nazar Boyko

Good question! My bet is the major tools move fast,since teams like typescript eslint and the framework language tools have been tracking the native port since the preview days and are mostly waiting on the stable API. The long tail is a different story, and smaller plugins that reach into compiler internals will probably need a few cycles. In practice I think most teams will be able to drop the dual setup within a release or two after 7.1.

Thread Thread
 
jeremy_6a02b3 profile image
Jeremy II

That seems like a realistic timeline. It will be interesting to see how quickly the smaller plugins catch up. Thanks for sharing your thoughts.

Collapse
 
joeybart profile image
Joey Bart

We actually noticed something similar on our team. After upgrading, one of us thought the TypeScript check hadn't even run because it finished so quickly. We ended up checking the logs just to make sure everything was working. The funny part is that nothing changed from a developer's perspective. Same code, same types, same errors. We just spent less time waiting. Those kinds of improvements don't usually make flashy demos, but when you're working in a large codebase every day, they make a bigger difference than most new language features.

Collapse
 
nazar-boyko profile image
Nazar Boyko

That is my favorite kind of upgrade story, when the tool gets so fast you assume it must be broken. It says a lot about how much waiting we had all normalized that a passing check now looks suspicious enough to go read the logs. Thanks for sharing a real world data point, this is exactly the boring but huge kind of impact I was trying to describe.

Collapse
 
joeybart profile image
Joey Bart

Exactly. It's funny how quickly "waiting" became part of our workflow without anyone questioning it. Now the fast feedback almost feels wrong.

Collapse
 
hoseinmdev profile image
Hosein Mahmoudi

Your explanation of Go's shared-memory multithreading vs. JS worker threads is probably the clearest breakdown of TS 7 I've read so far! 🎯

Also, pointing out why the team chose Go over Rust (to mirror the codebase shape rather than rewriting memory logic from scratch) was such a great engineering insight.

Don't worry about the AI usage for Englishβ€”the article flows naturally and the technical depth is top-tier. Thanks for clearing up the myths around Node's type stripping vs Native TSC! πŸš€

Collapse
 
nazar-boyko profile image
Nazar Boyko

Thank you, that is very kind! Especially the note about the language, it means a lot. The Go over Rust decision is my favorite detail of the whole story too, because the boring choice is exactly what made the compatibility promise possible. Glad the type stripping section helped clear the myths up!

Collapse
 
hoseinmdev profile image
Hosein Mahmoudi

You nailed it! Sometimes the 'boring choice' in software architecture takes the most engineering discipline. Loved the article, and looking forward to reading more of your deep dives in the future! πŸ™ŒπŸš€