It is an accumulation of complexity that, for backwards compatibility, we get stuck with.
The browser should be simple.
If the focus just stayed on making wasm better for web development, folks can use any language they want and the API surface area can stay small.
And I personally feel like (I may be wrong) that at the end your proposal and the wayland proposal might be the same..
The problem with wayland protocol/your proposal is the fact that such things have already been tried (java applets) and they were insecure, and accessibility was a mess, so reverting back to it does feel like a massive chaos since javascript was created to solve that problem..
I am not a js advocate, honestly I wish that ephemeral running of apps cross platform becomes genuinely easy (in my mind nix-shell comes) There is htmx which is nice too I guess but I think I still need some js to sprinkle in some more interactivity/animations.
Astro with htmx / islands architecture kinda feels the best, imagine using svelte/vue/react and htmx+golang in the same project..
But the TypeScript compiler API is synchronous, so there's a problem.
What you want to do is asynchronously walk the import graph, resolving import specifiers along the way with something like es-module-lexer or TypeScript's light parser, then when all the input files are collected, pass them through a compiler host to the compiler.
This is what the Lit team's Playground Elements do, which compile files on a worker for embeddable interactive code samples: https://github.com/google/playground-elements
But it doesn't use DOM APIs, so you can run it in a worker without any issue. Monaco (the embeddable distribution of VSCode) does that.
The even bigger issue is that the TypeScript compiler is gigantic — like 10 MB, which is just a nonstarter for something you'd need to embed in every page of your site.
Being in a worker only causes the synchronous fetches to not block the main thread. It's still terrible for performance as you lose all ability to load files in parallel.
It's really not that difficult to pre-traverse the import graph and fire off as many parallel fetches as the browser will allow.
Thanks, you're right, I was looking at the unminified version. Minified is 3.4 MB uncompressed, 730 KB compressed. That's still crazy considering that you could avoid it by compiling your code on the server (which can be extremely fast if you disable type-checking) rather than shoving that responsibility onto your user's browser. Might be reasonable for a big web application with megabytes of other scripts, but not for a normal website.
But there are cases where you want to be able to run arbitrary TypeScript in the browser - in our case it was inline editable code samples - and for that running the TS compiler efficiently in a worker is great, and 730k isn't that bad. You probably also have 500kB - 1MB for a decent code editor too.
> TypeScript is still second-class citizen with regards to browser adoption, there is a proposal to fix that, but until then we have to use tooling, bundlers, build steps that are an impediment for when you want to quickly create a short demo or PoC.
(Of course, just for "a short demo or PoC," but will anyone be motivated to rip it out before that's no longer feasible?)
So I assumed you were talking about something similar. But using this approach to compile user code makes a lot of sense.
The issue is that the CompilerHost and LanguageServiceHost interfaces expect a synchronous filesystem API, and downstream from that the compiler internals all expect synchronous access to files.
There's a very long standing issue open to make the API async, but I'm pretty sure it's obsolete now in the face of the tsgo work.
Seems tsc itself requires node, but surely an api that takes a ts file as a string and returns a ts file as a string should be possible?
Tade0•1d ago
I've seen an alternative approach, where the TS code is sent for compilation to a dedicated server - dismissed that idea as over engineered, but then I learned that the swc WASM package clocks in at over 5MB.
I love the name BTW.
carl_dr•1d ago
> tsbro solves this by completely bypassing the browser's import system using synchronous XHR, transpile with swc wasm and a sophisticated ESM-to-CJS transpiler so that synchronous require is used everywhere:
Tade0•1d ago
It's also not using a service worker.