Tsrs: A Port of TypeScript to Rust

13 hours ago (blog.cloudflare.com)

Hey there, TypeScript team member here. The tsrs project has been extremely interesting to see come together. We've been working with the maintainers to better understand how tsrs is fast and what sorts of optimizations it uses are safe. We even did our own Rust vibe port and what we currently suspect is that a lot of the speed does not just come down to language choice, and some of what is going to make TS 7.1 faster and leaner (see the charts in the blog post) actually comes from optimizations discovered in tsrs.

We think the wasm and oxlint integration makes a lot of sense for Cloudflare's needs, so this investment makes sense. At the same time, we'll be working hard and collaborating to make the official TypeScript toolset faster and even more efficient.

Congrats to the tsrs team on making this official. We're excited and we look forward to continuing on collaboration!

  • At this point, why invest further in TSGO?

    No matter how many optimizations can be ported from tsrs to ts-go, Rust will be more efficient and enable the WASM use case.

    The premise of porting the compiler from TS to GO was ease of migration due to Go's garbage collector. That doesn't hold anymore? AI doesn't care how hard or easy a migration is if a test suite exists.

    • > That doesn't hold anymore? AI doesn't care how hard or easy a migration is if a test suite exists.

      Sure, but that only matters if migration is going to be the last thing anyone does on a project. Unless you think typescript 7.1 ought to be enough for anybody, it also matters what the typescript team wants to write/read/reason in.

      2 replies →

    • I just vibecofed tsasm. tsrs is obsolete now and anyone who still uses it is hopelessly behind the times. The tsrs team should delete the repository immediately and join my project.

      15 replies →

    • Your answer is within the comment you wrote. AI is maintaining tsrs whereas humans are maintaining tsgo.

      Your question boils down to "why would humans maintain something?" which could have a variety of answers depending on context.

      7 replies →

    • I never understand why people say things like this. It is not uncommon for languages to have multiple implementations, everything must not be abandoned for Rust man.

      3 replies →

    • Because TSGO is stable and compatible?

      I assume that most of the speedup in ts-rs does not simply stem from using a language without garbage collection, but actually from doing smart optimizations that can be done in any langauge.

      Similar to how uv in the Python world explained that their implementation being in Rust has very little to do with the most impactful speedups they did.

      1 reply →

    • TSGO is already plenty fast and overkill for most projects.

      Sure the Rust version is faster but the difference is probably only noticeable in the top 1% largest projects.

      22 replies →

    • Another advantage of AI, though, is that it becomes easier to maintain more than one TypeScript compiler. Perhaps there's some benefits to having some diversity?

    • Please you port it if its so easy, the tests are available on gh. I wont be using an llm ported ts compiler anyways, and neither would many others

      Its a great way to divide and kill the popularity of your project. I made sure bun is no longer used in my devices or projects that depend on it for example, I'm not alone in this.

  • Thanks for the response and it is encouraging to hear that there's more to this project than vibe coding! Sounds like some interesting things were found in the process, and I'm all for vibe coding as a way to learn new things.

    • Im not because nobody actually ever learns anything. For every one person that learns something the other 99% of the population gets lazier and dumber, ponder how that might play itself out.

      This is probably the most harmful tech ever created simply because how many people trick themselves into thinking they're smarter while actually becoming much dumber. We're actually cooked.

  • +1 from what I’ve seen, porting apples to apples to rust only impacts performance by a few % (sometimes in the wrong direction). The main speed up comes from algorithmic improvements that can also be applied to the original project.

  • Been with TS for many years now and the work your team's done over the years is amazing. Thank you

  • Thanks for the input, glad to hear both parties benefit.

    Could you elaborate on what type of optimizations were added to TS 7.1? As in, were they more algorithmic or related to memory management?

    • If I recall correctly, a few of both - there were instances where some work could be done more lazily/minimally (https://github.com/microsoft/TypeScript/pull/64476), and there were instances where we changed our allocation patterns and played around with some struct layouts. We originally strived not to drastically reorganize our data structures to make things easier to port, and we have more flexibility now. We're continuing to experiment more here.

  • Ah I was gonna ask what happened with tsc-rs by Theo but looks like you guys are merging it in, at least it won't be a waste of his $500k in token spend, lol.

It appears they're using a unique memory model (https://github.com/oxc-project/tsrs/blob/main/docs/PORTING.m...) to overcome the challenge that prevented the TypeScript team from choosing Rust to begin with: Rust has no GC and porting from a GC language to it often requires restructure of data.

Essentially, they fake a GC via never-freed arenas for long-living objects. It's interesting that Rust can do that (hopefully soundly)!

  • From the file:

    >Create with P::new(value). p.get() returns &'static T. [...] unless an explicit recycling site proves them dead

    It's unsound, the LLM/human is doing the proving. They've hidden unsafe in an abstraction without removing the unsafeness. Using the arena allocator's lifetime would have been safe and easy (bumpalo recommends this AFAIK).

    I'm guessing a sycophantic LLM either found or praised this load-bearing seam.

    Never deallocating would have been sound (missile memory management: https://devblogs.microsoft.com/oldnewthing/20180228-00/?p=98... ).

  • Wouldn't that eat the whole ram?

    • Compilers often just build up more and more data structures in memory until the end when they then release everything more or less at once. With an arena you can then just throw away the whole arena at the end, assuming there are no resource handles that need to be closed in drop().

      A long time ago I read an article about someone speeding up a C++ compiler that is itself written in C++ (was it g++? maybe clang?). They simply patched out delete so it did nothing. The compiler used marginally more memory but ran much faster, since releasing all the small objects one by one is just useless work at the end of the compilation.

      A GCed language has a similar behavior and could therefore be fast in that case. It just builds up all the objects and then when the program exists it doesn't have to GC them all, it just throws away the whole process memory. So I can imagine one could "optimize" a compiler written in a GCed language by deactivating the GC.

      1 reply →

Ah took me a while to understand the reason behind this.

It wasn’t “let’s build a faster Rust based Typescript compiler” at all. That was a nice side-effect.

They needed a Typescript compiler that can run on their WASM only sandbox. So the only existing option was to export tsc Go to WASM, but that comes with the full Go runtime.

And to avoid that cost, they experimented with a Rust compiler and turns out it’s even faster than the reference tsc/Go implementation.

  • > It wasn’t “let’s build a faster Rust based Typescript compiler” at all. That was a nice side-effect.

    Then why are the performance graphs the headliner topic in the article? The WASM sandbox is barely a footnote.

    • > Then why are the performance graphs the headliner topic in the article?

      If you’ve got it, flaunt it?

      > The WASM sandbox is barely a footnote.

      This one is a real head scratcher. The sandbox was clearly what set them on this path.

      Maybe they believe the performance gains are worthy of being discussed by themselves?

It's exciting to see the speed gains. I use TypeScript every day on a large codebase, and it is too slow to run locally. I don't love this change though:

> However, frontier AI models can now do large-scale ports almost independently in a matter of days

> I wrote zero code. Not "barely any". Zero

So we are going to move from a carefully handwritten port to an entirely AI-generated port. I know this is the way the industry is headed, I use coding agents a ton. But I still review their output because they often don't make sound architectural decisions. Maybe this is a sign that my way of working is going away. I'm not sure how to justify that kind of time spent when someone can do the same thing in a matter of days with barely any effort.

I am working on my own language now, I've spent most of this year on it. The idea that someone could just replace it in a matter of days is wild. Wonder how the TS team at Microsoft feels about this.

  • > The idea that someone could just replace it in a matter of days is wild.

    They didn’t design a language that millions of human engineers enjoy (?, lol) using. They took an existing codebase and ported it. Yes, the porting part is easier now but only because another project and spec exist.

    • While this is true - and I see the same sentiment as i am about to make ad nauseam - it is kind of amazing how far the goal posts have moved in such a short space of time.

      2 replies →

    • That's fair, I was thinking the same – porting must be simpler, especially if there's already a substantial test suite

  • If TypeScript has the integration testing framework in place to verify that the compiler actually works (and it should) - then, presumably, you should be able to swap in a Chinese Room black-box and - at least - know that it works.

    You do have to be worried that it's possibly installing trojan horses on your computer while compiling code, or any other number of unwanted side effects.

    But you can and should be able to have integration testing in place to know that a compiler - at a minimum - actually works.

    • Totally fair. The thing is, though, agents often write code in ways I don't expect, and I don't think any human would write, which makes me think that code may also break in a way that no human expects or would have written a test for.

  • Your way of working is definitely going away. And quickly. The idea of reviewing code today is already a questionable use of time. In a few more months to a year it will clearly be a waste of time.

    • The only group of people saying this are those who didn't have much technical ability to begin with.

    • Found the meat proxy. Your kind will be the first to be replaced. Useless without the machine doing the actual work of thinking.

AI isn't improving productivity if EVERYONE is trying to reinvent the same f*king thing. What are we doing here? Why publish any open source software at all if someone is gonna swoop in and vibe something better™ faster™ and more memory efficient™ the next day?

  • Just like science, open-source is a collective effort to build increasingly better solutions to the problems we have. We cannot ignore individual benefits in contributing, but that is not everything. It’s about collaborating/competing to build better things, standing on each other’s shoulders.

    • Just to put everything in perspective, I recognize fully that Cloudflare had a use case for tsrs with WASM sandboxing. I am addressing your larger point about this sort of thing becoming the norm.

      > We cannot ignore individual benefits in contributing, but that is not everything.

      Individual benefits are the very foundation of most collaborative efforts. Pharmaceutical companies get payouts via patents for researching life-saving medicine. Even with money taken out of the equation, many academics slave for years over their research in hope of recognition either via Tenure or Nobel Prize. Ignoring the fact that people want credit for their work is dangerous and irresponsible.

      Forking projects that are near-complete or have already undergone major refactors just to snipe them last-minute with vibe coded efforts is going to kill collaboration. I'm never building another project in the open again because that is precisely what I'm aiming to avoid.

What strange times. A few years ago seeing a headline like this, my jaw would have literally dropped. Instead I'm wondering what kind of software projects will have meaning in the future if this headline feels common.

Shameless plug of my Typescript C# port. It's a case study with some interesting (perhaps) notes from me in the README about approach, performance, and cost(~$75).

https://github.com/stepwisehq/typescript-dotnet

  • I'm going to do a taboo and comment on my own comment.

    I didn't push performance in a way that would cause big deviations from the Golang project's algorithms and data structures; similar to how the TS team didn't want to deviate too far from the JavaScript source till now. Aggressive unmanaged arenas and object pooling was the direction I would have pursued..

    The GC in DotNet is a source of major frustration for a tool like this. Without tuning lots of gen 0/1 work occurs to determine if objects should be promoted. The tuning is still not an ideal solution IMHO. Fully unmanaged arenas and aggressive object pooling could help here, but an alternative GC may be part of an ideal, comprehensive solution.. I have have a play with ZeroGC.

    There is a warning on the repo that it's not maintained, but I've been curious about the process of updating it to sync "upstream" changes. And it sounds like the TypeScript team are going to start incorporating some of the performance techniques identified in the Rust port in the 7.1 release so... I'll probably at least sync it to up to 7.1 and keep it as an active experiment and case study on LLM porting and DotNet AOT performance.

    It's just good fun.

According to voidzero, this port is up to 8x faster than TS 7.0 & ~70% less memory.

Microsoft should seriously consider porting typescript to rust at this point

I use the Typescript compiler to report errors to the shell, but that's it.

Both Bun and Node.js will execute Typescript directly without a compile step. If you are able to write your own front-end bundler then the front-end code also gets the same type stripping from either Bun or Node.js. Since both Bun and Node.js start up my large applications about twice as fast as the Typescript compiler executes I don't see any reason to bother.

  • This is like saying you only use your car for transportation, but you don't sleep in it anymore because your bed is more comfortable.

I'm tired of all the new tools that comes out every day, but I would say, this is basically the Vite team and if they implement it with Vite+, then I'm all for it, less decisions about tooling to be made, one config file, etc.

I guess it will be soon that typescript won’t matter anymore since agents will be writing code is Rust compiled to WASM or similar for everything. typescript added human readability or JavaScript, if no human is coding, I don’t see the point of wasting tokens on this.

  • > typescript added human readability

    Ehm no, added type safety, and dealing with a type checker it's exactly what agents need.

    > if no human is coding

    Nope outside the bubble there are many still hand coding(me too)

    > I guess it will be soon that typescript won’t matter anymore since agents will be writing code is Rust

    Oh hold on a second isn't Rust the same as Typescript "adding human readability"?! Why not trashing Rust and just have LLMs output WASM directly? XD Wasm which is basically useless outside the browser or some microvms on the edge, and in the browser you don't even have an interface for directly rendering anything and still have to deal with the dom

    You either are highly non technical, very junior or I just don't know

  • Which language do you write to run code in browsers, especially that can manipulate DOM?

    You need a quick reality check.

Or we can just drop TypeScript completely and type-check JavaScript directly.

With HM-style type inference, row-polymorphism, sum types, type classes for overloading + operations, recursive types for object methods, and type annotations for edge cases.

I've been working on this since before TypeScript existed. Latest incarnation: https://github.com/sinelaw/inty

Demo: https://sinelaw.github.io/inty/ (you may need to reload once)

  • typescript is two things: a language, and a type system.

    that same type system exists in the javascript language (jsdoc). doing those type checks is the 'slow' part that makes go / rust appealing. not just stripping types to emit js.

  • isn't it better to use JSDoc ?

    • I assume you mean jsdoc + tsc in js type checking mode (tsc --allowJs --checkJs --strict)?

      inty infers more - including generics (parametric polymorphism), while tsc is more of a simpler local inference.

      inty is more strict - it accepts less programs than tsc would. This is mostly on purpose (to our benefit) as some of those programs have unsound code like array covariant (downcasting array members of the wrong type). tsc makes it easier to slip through these bugs.

      And if tsc + jsdoc is good then the same question remains (do we really need the TypeScript language?)

I wonder if something similar has been attempted with Python. CPython is a project where I don't know how they are taking advantage of AI.

  • The problem with Python is that the whole ecosystem is based on CPython’s implementation details, so every change inevitably breaks something and requires effort of package maintainers to fix compatibility. There is no test suite an agent can follow.

All of this just for enabling the WASM use case? Why not keep supporting Deno then that is written in Rust? To me it just sounds like a technical ai journey and a blow to the go port

  • I think it is a response to tsc-ts and scriptc from Vercel. CloudFlare and vercel CEOs have a personal competition going on.

I benchmarked tsrs a few weeks ago. I was testing out tsgo, ts-rust, tsrs, and bun for typechecking on our monorepo. tsrs is definitely awesome, it is very memory efficient when bumping up the number of threads. Not as efficient as bun, but it has incremental checks, which bun does not have.

I use oxc tooling and it's great to see the rust rewrite singularity in action and get to ride the fastest horses, but I would like that they made a branch for 7.2 as experiment to see how it compares. Maybe this ends in a win for Microsoft, they could cut operating expenses by keeping just Anders Hejlsberg in a hammock reciting invariants to claudpilot.

I think we'll see TypeScript ported to minecraft ported to rust ported to typescript before GTA6.

Obligatory reminder that their needs from a TS compiler are extremely different from a regular web developers iteration cycle. They are trying to run millions of these while saving on costs.

You almost definitely don't need to immediately plan to switch.

  • > This enables new possibilities when combined with agents: You are now able to run a development toolchain end-to-end in a fully sandboxed environment on Cloudflare.

    True. Looks like main use-case is AI Agent Sandboxing

this is insane! saw a quote tweet of this by an infra engineer at chat gpt who said “ I'm looking at migrating over for the ChatGPT codebase and saw ~70% improvements on both wall time perf + peak cpu/memory usage.

this is great for getting work done faster but also much better if you want to run concurrent agents/worktrees at scale”. https://x.com/feedthejim/status/2112584843368570921?s=46

then i went and tried this on my own open source harness. type checking went from 10 seconds to under half a second and uses a quarter of the memory. madness

so rust is now go-to slop language? can't you guys use C or something. I want rust back.

  • Rust is basically the perfect language for LLMs because it has a strong, comprehensive, and strict compiler. For coding you really need a tight loop for models so they can iterate. C doesn’t accomplish this because it’s far too “anything goes” so bugs slip through. Dynamically typed languages don’t work either because their source code doesn’t contain enough context.

  • What? You realize how many people now are excited about Rust that were not before? I am, for one.