Sign in

Andrew Branch

@andrewbran.ch
1.1K followers 107 following 51 posts

Working on the TypeScript API at Microsoft.

PostsRepliesMedia
Reposted by Andrew Branch
Remco Haszing @remcohaszing.nl · 06/09/2026
I published a TypeScript content mapper for CSS modules. This gives you type-safety and definitions when importing CSS in TypeScript. github.com/remcohaszing...
On the right is a pane of CSS code. On the left is a pane of TypeScript code that imports the CSS as a module. The hover info of the imported CSS class shows the CSS block. There’s also an unknown class name, which has a red squiggly underline.
6808
Andrew Branch @andrewbran.ch · 04/09/2026
Is this a custom app to track the build?
101
Reposted by Andrew Branch
Jiahan Chen @chenjiahan.bsky.social · 01/09/2026
Excited that TypeScript will finally support module types based on import attributes! Bundlers and frameworks can now provide accurate types for custom imports:
27116
Andrew Branch @andrewbran.ch · 31/08/2026
It was my bad for forgetting to relabel while thinking about what to do. But rest assured the bots don’t control us 🙃
070
Reposted by Andrew Branch
NullVoxPopuli @nullvoxpopuli.com · 26/08/2026
Ember now has preliminary TS7 support ~ via the content-mappers feature that merged in TS last week Testers wanted! (requires TS Nightly)
2147
Reposted by Andrew Branch
Jiahan Chen @chenjiahan.bsky.social · 20/08/2026
The TypeScript content mappers PR just merged and is likely to land in 7.1 🎉 This could open a new chapter for everything built on and around TypeScript github.com/microsoft/ty...
github.com
Content mappers by andrewbranch · Pull Request #4712 · microsoft/typescript-go
Implements microsoft/TypeScript#63800 (comment) Overview Content mappers are external integrations that allow TypeScript to include otherwise unsupported file types in a program. They transform a f...
3449
Andrew Branch @andrewbran.ch · 18/08/2026
Uh oh. SymbolFlags.All?
120
Reposted by Andrew Branch
Remco Haszing @remcohaszing.nl · 17/08/2026
My editor using mdx-content-mapper is now showing TypeScript info for frontmatter and code blocks.
An MDX file with two JavaScript code blocks. One is hovered and shows information about the code. The other highlights a type error.An MDX file with YAML frontmatter data and a variable named frontmatter. Hover information for the frontmatter variable shows the TypeScript type of the frontmatter data.
1275
Andrew Branch @andrewbran.ch · 17/08/2026
APIs are available in nightlies and some tools have started building with them to get ready for 7.1. But there will be breaking changes, so if a particular tool is no longer in development, it will never work with the 7.x line.
041
Andrew Branch @andrewbran.ch · 17/08/2026
FWIW, every announcement since at least April has said that 7.0 will not include the programmatic API that tools need. The blog posts have instructions for installing 6 and 7 side by side so you don’t have to temporarily downgrade. It’s not broken, it’s not included yet (which was the plan).
241
Andrew Branch @andrewbran.ch · 16/08/2026
Yeah, that doesn’t seem like a great trade off to me… there’s also the reality that any big shift from TS 6 that doesn’t strictly need to happen just makes it harder for people to move, on top of the changes that do really need to happen.
120
Andrew Branch @andrewbran.ch · 15/08/2026
That said, I don’t think I can accurately explain exactly how to attribute the 3x to 4x so I won’t try to hand wave too much. Anders did some videos and interviews after we announced that might get into the weeds better than I can.
010
Andrew Branch @andrewbran.ch · 15/08/2026
Some of both—JS of course doesn’t give you direct control over the layout. We had some big efforts to monomorphize access in JS but doing it across every object was impossible. We were definitely careful with layout/design in Go (e.g. avoiding access through interfaces in hot paths).
120
Andrew Branch @andrewbran.ch · 15/08/2026
This is what I love about open source! We all get better and smarter and faster together.
030
Andrew Branch @andrewbran.ch · 15/08/2026
It varies, but at least in the early measurements it was typically 2.5x from parallelism and 4x from everything else.
110
Andrew Branch @andrewbran.ch · 15/08/2026
Not yet. As for perf, it depends. The more separate requests, the more IPC overhead adds up. Wasm builds bring their own perf penalty to Go. I’ve seen tools get faster, stay the same, and get slower after moving to TS 7.
100
Andrew Branch @andrewbran.ch · 15/08/2026
How would you envision that working?
120
Andrew Branch @andrewbran.ch · 15/08/2026
I think 100% of what I showed actually shipped in 7.0. We haven’t talked about it a ton because we’re kind of at full capacity implementing things we know still need to get done, so I wanted to be a little strategic about the volume of feedback we get. Bit it’s time to start expanding a bit more.
120
Andrew Branch @andrewbran.ch · 15/08/2026
Now is a good time to start building with the API and sending feedback my way on GitHub. What are you still missing to be able to move your API-using projects to TS 7?
160
Andrew Branch @andrewbran.ch · 15/08/2026
What’s next? Content mappers, I hope! github.com/microsoft/ty...
A Vue file with TS intellisense working, and the same errors showing in the CLI with `tsgo --runExternalCode`
160
Andrew Branch @andrewbran.ch · 15/08/2026
This LSP-connected API method is why everything goes through immutable snapshots. You can continue to work with immutable state for as long as you want, even if the user has moved files or continued typing.
140
Andrew Branch @andrewbran.ch · 15/08/2026
This simple example is running in the extension host, but you can imagine passing this connection to your own LSP server, serving additional completions or hovers in TS files by combining its own logic with type checker queries.
The demo extension working, logging "add, subtract" in a math.ts file
150
Andrew Branch @andrewbran.ch · 15/08/2026
Let's do something totally different. Here's a VS Code extension, which gets a sidecar API connection to the TypeScript LSP that was already running. All the same APIs are available, and now you can inspect the projects the user has open in their editor. Here we're logging the exports of .ts files.
A VS Code extension calling a cross-extension API to get a pipe to connect to the TS 7 LSP and construct an async API instance from it. A change handler gets the default TS project for the file and uses its program and checker to log the file's exports.
150
Andrew Branch @andrewbran.ch · 15/08/2026
So far, almost all of this code could be mistaken for the old TS 6 API. But under the hood, a lot of care has to go into pretty silly things like making sure when you get the same Type or Symbol twice, they have reference equality. That doesn't come for free anymore.
two results of getSymbolAtLocation are strict equal to each other
140
Andrew Branch @andrewbran.ch · 15/08/2026
Now for some transformation. The new AST is a hybrid of these "remote nodes" backed by binary data and normal JavaScript objects. The client can encode the result into the same binary format so the server can run it through the emitter, in this case. Here's a (dumb) codemod to fix our error.
A transforming visitor replacing a string literal "2" with a numeric literal 2 on the same file, then printing the transformed file to a string.
140
Andrew Branch @andrewbran.ch · 15/08/2026
If you're interested more in how this works, the approach was inspired by @marvinh.dev's great write-up of solving a similar problem in Deno.
marvinh.dev
Speeding up the JavaScript ecosystem - Rust and JavaScript Plugins
Up until recently, supporting JavaScript in Rust based tools has been deemed not worth it. The main concern is the overhead of the de-/serialization cost when sending data back and forth. But there is...
1150
Andrew Branch @andrewbran.ch · 15/08/2026
To demonstrate the laziness of file decoding, we can see that after recursively visiting one of the two statements in the file, 10 of the 20 nodes were actually materialized. (The timings here look slower than they should because the VFS is not yet production quality.)
Metrics showing 20 nodes were fetched and 10 were materialized, with 5ms of IPC transport overhead
150
Andrew Branch @andrewbran.ch · 15/08/2026
Every node materializes into an instance of the same class, all reading the same underlying buffer. The TS types lie and give each node a specialized type. Here, we see `kind` reading its value from an offset computed by the node's index in the flattened AST and the kind field's offset.
Another debug view showing the getter for `kind`, reading a uint32 from the underlying buffer
260
Andrew Branch @andrewbran.ch · 15/08/2026
But how exactly does that work? The tsgo process encodes the AST in a compact binary format and sends it all over. The client's SourceFile type wraps the Uint8Array and exposes getters for every property you could want to access. Children and other properties are lazily decoded on first access.
A debug view inspecting the RemoteSourceFile type at runtime, showing a DataView with an underlying ArrayBuffer.
1110
Andrew Branch @andrewbran.ch · 15/08/2026
Slightly more interesting: let's navigate a source file and use the type checker on some stuff. This found the return type 'void' from `console.log` and the return type 'number' from `add`.
Recursively visiting each child of the second statement of main.ts, getting the signature of call expressions, and logging the return type of those signatures. Output shows void (belonging to console.log) and number (belonging to add)
1110
Andrew Branch @andrewbran.ch · 15/08/2026
Let’s start with something basic like getting diagnostics. Not too much to say about this. Each API call like this is communicating over STDIO with the tsgo process. We'll see some details in a minute.
console.logging program.getSemanticDiagnostics, showing an assignability error as a JS object
1181
Andrew Branch @andrewbran.ch · 15/08/2026
The API comes in sync and async flavors. You import from "unstable" for now, but it's not going to change architecturally before 7.1. Breaks will be mostly targeted renames/moves. You access programs through obtaining immutable snapshots. There will be more ways coming soon. More on this later.
A TS file creating a sync API instance from "typescript/unstable/sync" with a virtual file system, and obtaining a program, checker, and emitter.
1161
Andrew Branch @andrewbran.ch · 15/08/2026
If you’re not stalking TypeScript PRs, you might be surprised how much you can do with the API in nightlies (and even in 7.0 stable), so here’s a tiny demo that I think hits some of the highlights. 🧵
A package.json in VS Code after npm installing typescript@next
412620
Andrew Branch @andrewbran.ch · 07/08/2026
A friend of mine was injured just last week at his workplace when an e-bike crashed through the building. Ah no wait it was a car
010
Andrew Branch @andrewbran.ch · 07/08/2026
I think so but I’m not sure of the timeline, @jakebailey.dev might be able to confirm
120
Andrew Branch @andrewbran.ch · 07/08/2026
They are not quite complete but they’re getting pretty close! Several projects (like ts-loader) have already started building against them. The feedback from those early adopters has been super valuable but I’m getting the sense a lot of folks don’t know it exists already!
061
Andrew Branch @andrewbran.ch · 07/08/2026
Thanks for mentioning the APIs and arethetypeswrong! ❤️ I feel like I need to get the word out that the compiler APIs are available today in nightlies, and even in 7.0, they’re just under “typescript/unstable” to make it clear that we reserve the right to make breaking changes before 7.1.
3134
Reposted by Andrew Branch
John Reilly @johnnyreilly.com · 31/07/2026
I've been busy experimenting with the new emit APIs that TypeScript 7.1 will bring. ts-loader now has basic support in place - here's how we got there! johnnyreilly.com/migrating-ts...
johnnyreilly.com
Migrating ts-loader to TypeScript 7.1 with AI
How I used AI to migrate ts-loader to TypeScript 7.1.
1121
Reposted by Andrew Branch
David Sherret @dsherret.dev · 30/07/2026
ts-ast-viewer.com now supports TypeScript 7 along with nightly builds of the typescript-go repository. It's not selected by default, but available in the dropdown.
Dropdown menu showing a TypeScript 7.0.2 selection on ts-ast-viewer.com
2295
Reposted by Andrew Branch
John Reilly @johnnyreilly.com · 28/07/2026
If you discount project references (and there's no API support as yet I believe), then all bar around 6 tests of ts-loader are now passing using the 7.1 tsgo TypeScript API! Not quite there yet but significant progress github.com/TypeStrong/t...
github.com
Support TypeScript 7.1 API by Copilot · Pull Request #1704 · TypeStrong/ts-loader
This PR is an attempt at using the TypeScript 7.1+ API. This pares back the earlier tsgo integration attempt to the new API alone. Instead of carrying both implementations, experimentalNativeApi no...
181
Reposted by Andrew Branch
John Reilly @johnnyreilly.com · 27/07/2026
Building upon the fine work of @pier.fumagalli.org / @titiancernicova.bsky.social / @andrewbran.ch I've been throwing copilot at the new TypeScript 7.1 API and ts-loader. Very early days but some progress! github.com/TypeStrong/t...
github.com
Add minimal experimental tsgo transpile path by Copilot · Pull Request #1704 · TypeStrong/ts-loader
This pares back the earlier tsgo integration attempt to the new API alone. Instead of carrying both implementations, experimentalNativeApi now routes through the tsgo API directly, with the existin...
292
Andrew Branch @andrewbran.ch · 27/07/2026
Awesome! FYI, transpileModule is coming soon too
120
Andrew Branch @andrewbran.ch · 25/07/2026
Probably not going to change that much, except for adding more stuff! There’s just no promise or stability until 7.1, but I don’t anticipate major changes.
020
Reposted by Andrew Branch
mary🐇 @mary.my.id · 25/07/2026
they coulda trained opus 5 to learn that typescript 7 is stable now because it simply refuses to believe oxlint with type checking enabled only takes 28ms to run
3952
Reposted by Andrew Branch
Pier Fumagalli @pier.fumagalli.org · 25/07/2026
Today’s Typescript 7 daily release finally includes my contribution to support “emit” via API! Right before the weekend, so I can waste it playing around with it 😛 Thanks @andrewbran.ch tor including it! npmx.dev/package-code...
npmx.dev
Code - typescript@7.1.0-dev.20260725.1 - npmx
Browse source code for typescript@7.1.0-dev.20260725.1
45610
Andrew Branch @andrewbran.ch · 25/07/2026
Thanks for working on it!
030
Andrew Branch @andrewbran.ch · 24/07/2026
🤞
120
Andrew Branch @andrewbran.ch · 15/07/2026
Yes! 🙌 This made my day!
010
Andrew Branch @andrewbran.ch · 09/07/2026
The water is extra glassy today
110
Andrew Branch @andrewbran.ch · 08/07/2026
I'm sure this was not meant to be personal, but it's hard not to feel a jolt of panic and defensiveness when the og-image of your sadness has my face in it 😅
130