Introductie van tsrs: een port van TypeScript naar Rust

Cloudflare en VoidZero werken samen met Max Schwenk van Owner.com aan tsrs, een Rust-port van de TypeScript-compiler. We voeren dit werk uit in nauwe samenwerking met het TypeScript-team en incuberen tsrs als onderdeel van de Oxc JavaScript-compiler toolchain.

Ons doel is om ontwikkelaars te helpen minder tijd te besteden aan het wachten tot hun code is gecontroleerd en meer tijd aan het bouwen. Door TypeScript sneller en geheugenefficiënter te maken, helpt dit ook om volledige ontwikkelomgevingen naar meer plaatsen te brengen, inclusief direct in je browser.

Om duidelijk te zijn: we maken geen fork van TypeScript. We geloven dat het TypeScript-team de volledige controle over het ontwerp en de richting van de taal moet behouden. Zij hebben een langetermijnvisie gehandhaafd terwijl ze de adoptie van TypeScript binnen de JavaScript-gemeenschap hebben gestuurd. Dat willen we niet veranderen.

Het TypeScript-team kan op veel vlakken snel bewegen, maar voor sommige functies besteden ze mogelijk jaren aan het verkennen van opties en het maken van prototypes voordat ze de juiste implementatie kiezen. Een Rust-port moet deze beslissingen nauwgezet volgen, anders zal het uiteindelijk uiteenvallen en incompatibel worden. We moeten de TypeScript-taal strikt behouden op basis van de oorspronkelijke implementatie – en het TypeScript-team moet uitsluitend verantwoordelijk blijven voor het bepalen hoe dat eruitziet.

Prestaties en geheugenverbruik

Vroege benchmarks van onze Rust-port van TypeScript zijn veelbelovend: tsrs is tot 8x sneller en gebruikt ongeveer 70% minder geheugen vergeleken met TypeScript 7.0 wanneer hetzelfde aantal type-check workers wordt gebruikt.

Zoals je kunt zien, brengt de volgende versie van TypeScript al veel prestatieverbeteringen met zich mee, waardoor TypeScript 7.1 beta tot 2,5x sneller is dan TypeScript 7.0. Sommige van deze optimalisaties zijn upstream gekomen vanuit tsrs, en we hopen er meer te vinden.

Je hebt mogelijk recente benchmarks gezien van verschillende TypeScript-ports met diverse prestatieclaims, vaak doordat er grotere machinestypes en andere opties werden gebruikt vergeleken met de standaardinstellingen van TypeScript. We hebben met het TypeScript-team samengewerkt om ervoor te zorgen dat de bovenstaande benchmarks dezelfde configuratie vergelijken.

Standaard wordt tsrs geleverd met een adaptieve configuratie die afhankelijk is van het machinetype, wat meer geheugen gebruikt maar nog sneller is.

Probeer tsrs

TypeScript in Rust streeft ernaar een getrouwe port van TypeScript te zijn. Je kunt een experimentele release proberen door het tsrs-pakket te installeren via npm:

npm install tsrs
npx tsrs

Waarom nu?

We hebben door de jaren heen veel pogingen gezien om TypeScript naar andere talen te porten. Vanwege de complexiteit is slechts één van de ports geslaagd: de port van TypeScript van JavaScript naar Go door het TypeScript-team.

Echter, moderne AI-modellen kunnen nu grootschalige ports bijna onafhankelijk uitvoeren in een kwestie van dagen. We hebben nu 'slopforks', getrouwe ports en volledig opnieuw gearchitecureerde versies van TypeScript in Rust of C++ gezien. Er is duidelijk een vraag naar een nog snellere TypeScript.

Waarom Rust?

Je vraagt je misschien af: "De Go-port van TypeScript maakte TypeScript al 10x sneller en veel geheugenefficiënter dan de vorige versie geschreven in TypeScript. Waarom is dat niet genoeg?"

Het gaat echter niet alleen om snelheid. Rust biedt enkele unieke voordelen, zoals het draaien in WebAssembly (Wasm). Het verhaal van Rust + Wasm is altijd sterk geweest, en een van de redenen ligt in de fundamenten van het taalontwerp van Rust. Wanneer je een Go-programma compileert naar Wasm, moet je de garbage collector van Go meecompileren. Maar het geheugenbeheermodel van Rust maakt eenvoudige geheugeninteracties tussen een WebAssembly-guest en host mogelijk. Dit is een van de belangrijkste zaken die Rust veel beter geschikt maakt voor het WebAssembly-gebruiksscenario: geheugenefficiëntie.

Cloudflare Workers ondersteunen Wasm al lange tijd. Een paar weken geleden hebben we aangekondigd native Rust in Workers te ondersteunen met het nieuwe Emscripten-doel voor wasm-bindgen. Wanneer je volledige software-build- en deployment-systemen in strakke loops op Workers draait, betalen de voordelen van een kleine geheugenvoetafdruk zich snel terug. Dit betekent dat je deze workloads zo efficiënt kunt draaien dat het nu mogelijk is om volledig ingekapselde developmentsystemen te draaien op plaatsen waar dat voorheen niet kon.

In combinatie met agents maakt dit nieuwe mogelijkheden mogelijk: je kunt nu een development-toolchain end-to-end draaien in een volledig gesandboxte omgeving op Cloudflare. Maar met Wasm kun je die omgevingen ook veilig aan de client-zijde in je browser draaien, of op een embedded device, of een IoT-applicatie.

Hoe zal de tsrs-port worden onderhouden?

Ten eerste werken we samen met Theo Browne om tsc-rs en tsrs samen te voegen tot één pakket dat alle functies van TypeScript ondersteunt, inclusief het Language Server Protocol (LSP) en content mappers.

Ten tweede hebben we veel succes gezien met de manier waarop we Vinext synchroniseren met de upstream, Next.js. Elke ochtend beoordeelt een agent de wijzigingen, haalt diffs op en opent tracking-issues voor alles wat Vinext zou kunnen beïnvloeden. Elke nacht wordt de compatibiliteitsmatrix opnieuw gegenereerd terwijl we de Next.js-testsuite draaien tegen Vinext. Wanneer een van deze tests of issues een gat onthult, zijn agents nu in staat om de wijziging in beide codebases te identificeren, een reproductie te bouwen, relevante tests te porten en een fix voor te stellen.

We zullen hetzelfde proces toepassen op TypeScript, waarbij we uiterste zorg dragen dat we geen afwijkend gedrag introduceren ten opzichte van de upstream TypeScript. Wanneer we prestatieverbeteringen tegenkomen, zullen we proberen deze terug te brengen naar de TypeScript Go-codebase, zodat iedereen er profijt van heeft.

Tot slot erkennen we dat er momenteel enkele verschillen zijn met de upstream-versie van TypeScript, zoals bijvoorbeeld de volgorde waarin diagnostics worden geprint. We streven ernaar deze verschillen tot een minimum te beperken tegen de tijd dat we een stabiele release publiceren.

Wat is de volgende stap?

Cloudflare is al de thuisbasis van veel gratis en open source Rust-tools die het JavaScript-ecosysteem aandrijven, zoals Vite, Rolldown, Oxlint en Oxfmt. Met meer dan 10 miljoen ontwikkelaars die op Cloudflare bouwen, vinden we het erg belangrijk om de onderliggende developer toolchain sneller, draagbaarder en gemakkelijker uit te voeren op meer plaatsen te maken. We zijn enthousiast om te experimenteren met diepere tsrs-integraties in onze stack, bijvoorbeeld voor type-bewuste lint-regels in Oxlint.

Net als bij Vinext is ons doel om tsrs te draaien als een goed onderhouden, gezond open source-project — zonder in de weg te zitten van TypeScript zelf. Het Oxc-team is al begonnen met het refactoren van de codebase om deze sneller te maken, minder geheugen te gebruiken en onderhoudbaar te maken. We weten dat het TypeScript-team dit serieus neemt – zij experimenteren met geheugen- en prestatieverbeteringen voor tsc. We kijken ernaar uit om samen te werken met het TypeScript-team en de JavaScript-gemeenschap om samen de beste en snelste implementaties van TypeScript te bouwen.