ts-rust: what Theo’s AI compiler experiment means for developers
What the Rust port does, how to read its speed results, and three practical tools you could build with it.
Theo’s experiment asks a direct question: can an AI help turn an existing compiler into a useful Rust implementation? The result is ts-rust, also called tsc-rs. It ports Microsoft’s native Go TypeScript compiler, rather than starting with a new language design.
For developers, the useful question is whether it checks the same code correctly and fits the tools they already use. This guide explains the project, the evidence behind its speed claims, and a few small things you could build with it. The video above is the discovery source. The technical sources are linked throughout; Qentrah has not independently run the port or its benchmarks.
What the project actually does
TypeScript adds types to JavaScript. A type checker can catch mistakes before your code runs—for example, assigning text to a variable that should contain a number. A compiler also has to find imported files, understand configuration and produce useful error messages. An editor may use its language server for completions and navigation.
The Rust port aims to preserve the behavior of the Go implementation. Its porting contract includes the order and content of diagnostics. A diagnostic is the compiler’s description of a problem, including its location. Matching those details matters when another tool expects a specific result.
| Part of the job | Why it matters to you |
|---|---|
| Find the same files | Imported code must be checked too. |
| Report the same errors | Faster checking is useful only if it catches the problems you need. |
| Preserve error locations | Your editor should highlight the right line. |
| Support your configuration | A small demo passing does not prove a large workspace will work. |
Here is a small example you can understand without knowing compiler internals:
// expected-error.ts
export const attempts: number = "three";The variable promises a number but receives a string. Compare both checkers’ error messages and locations, then change the value to 3. The error should disappear. This gives you one failing case and one valid case; checking only the failing case could miss a tool that reports an error on everything.
What the published speed results show
The project’s benchmark file records checks of a prepared VS Code fixture. TypeScript 7 took 7.44 seconds, the Rust 0.3.0 release took 4.65 seconds, and an unreleased Rust build took 4.55 seconds. Those three builds produced matching diagnostic hashes: recorded fingerprints of the diagnostic output.
Bun’s faster 1.65-second result is excluded from the chart because it reported no diagnostics on this fixture, compared with ten from the three plotted builds. The benchmark does not establish that it performed equivalent checking.
The chart keeps the released Rust build separate from the unreleased build. Its caption records the hardware, versions and flags. These are publisher measurements of native compiler execution, rather than browser performance or a complete application build.
How long the recorded VS Code check took
View data table
| Category | Median time (seconds) |
|---|---|
| TypeScript 7 | 7.44 |
| tsc-rs 0.3.0 | 4.65 |
| tsc-rs main | 4.55 |
How to use that result
You do not need a formula to read the useful change: the release saved about 2.79 seconds on this recorded check. That is roughly 37.5% less checking time, using the rounded values. Your project may behave differently.
| Observation | Practical meaning |
|---|---|
| 7.44 seconds → 4.65 seconds | A shorter wait on this fixture. Measure your own project before expecting the same saving. |
| Matching diagnostic hashes | Stronger evidence than matching the number of errors alone. It still covers only the tested input. |
| Native binaries were timed | This result does not tell you how fast a browser playground will be. |
| Checking is one build step | Downloads, tests and bundling can still dominate your total build time. |
If your build spends most of its time running tests, changing the checker may have a modest effect on the overall wait. If checking dominates, it may be worth investigating sooner. Record your current build stages first, then test the change on a branch.
Small projects you could build
The most useful starting point is a bounded tool with a clear result. These are proposed projects, not features Qentrah has implemented or deployments proven by the repository.
| Project idea | First useful version |
|---|---|
| TypeScript learning playground | Let someone edit one file and see the error location. Use a worker so checking does not freeze the interface. |
| Compiler comparison viewer | Show two sets of diagnostics side by side. Flag changed codes, messages and source positions before showing timing differences. |
| CI trial report | Run both checkers on one project. Save commands, versions, diagnostics and repeated timings in an artifact your team can review. |
For the playground, the WASM guide is the relevant starting point. WebAssembly lets a host run a compiled module. The guide describes an in-memory file interface, structured diagnostics and a source-build process; it explicitly does not publish a package from that directory. It also recommends a browser worker and records Safari limitations.
A browser version needs its own startup and repeated-check measurements. Supply the configuration and required declarations as well as the editable source. Otherwise you may be testing missing setup rather than the code the visitor wrote. Keep the first version to a single file before adding imports or a workspace browser.
Try it on your own code
The repository’s installation instructions document the npm package and command. Treat the project as an early release and keep your current checker during the trial.
- Use a disposable branch and pin the candidate version.
- Run the same project configuration through both checkers.
- Save complete diagnostics and exit statuses. Investigate any mismatch before comparing speed.
- Include the intentional error above, a clean file, an import case and a project-reference case.
- Time repeated checks on the same machine, using the same warmup policy and flags.
| Keep in your trial report | What it helps explain |
|---|---|
| Compiler and project revisions | Which exact inputs produced the result. |
| Commands and configuration | Whether the tools performed comparable work. |
| Complete diagnostics | What was missed, added or moved. |
| Individual timings in seconds | How much the results varied across runs. |
Evaluate editor completions separately if you plan to replace the language server. A successful command-line check does not establish that every editor interaction behaves correctly.
Put the AI cost story in context
The creator reports more than $400,000 in API-priced tokens for earlier attempts, followed by roughly $24,047 in API-equivalent usage for an Opus 5.5 run using Claude accounts. Those figures are reported usage valuations, rather than verified cash invoices or a controlled comparison of models.
The project history records different goals, stages and token-accounting categories. A minimal working port and a fuller compatibility target are different endpoints. The result is interesting as a public engineering experiment; the figures alone cannot tell you which model will complete your own port most cheaply.
For a similar experiment, choose the acceptance tests before running an agent. Keep the failed attempts, human interventions and stopping rule in the report. That makes the outcome useful to the next developer, who needs to understand what actually worked.
Where to go next
| Source | Use it for |
|---|---|
| ts-rust repository | Installation, releases and known problems. |
| Benchmark manifest | Timings, diagnostic hashes and input revisions. |
| WASM guide | A source-built playground integration. |
| Porting contract | What preserving compiler behavior means. |
Start with the comparison viewer or a small trial on your code. Both give you something concrete to inspect: the errors the tool found, the ones it changed, and the time it took to produce them.


