Every so often a language comes out that allows frontend developers to put something other than "JavaScript developer" on their CV.
First CoffeeScript, then Flow and TypeScript, then ReasonML, and now Rust with WASM & web macros.
Of these only TypeScript has been successful, partly because it's backed by Microsoft, but mostly because the code you end up writing is very close to JavaScript.
This is not a dig at Rust (which I love) but God help any developer inheriting a frontend codebase with random bits of Rust in 2024.
It's not really that; it's really just WASM. There's going to be a flood of this sort of thing from all sorts of languages, even multiple per language. It's early days yet and the ground is still being felt out, but eventually the Javascript qua Javascript foundation in the browser is going to be breached and a day will come when it is a minority language (still many years from now), for exactly the same reason that never in the whole history of computing has one general purpose programming language "won". Per https://www.destroyallsoftware.com/talks/the-birth-and-death... , Javascript is going to "win", but it's going to be Javascript in its incarnation as WASM, not the Javascript we know today.
"random bits of Rust in 2024."
And that's "the ground being felt out", not a fundamental problem. I expect to see WASM frameworks develop that are shipped out to the world as WASM and bind to any language. Decent odds they'll be developed in Rust for several reasons (performance not least of all), but you won't need to know that to use it in your Python WASM front-end app or some new WASM-primary language that is nothing more than a gleam in its creator's eye right now. If you don't want the chaos, hey, great. Even people who live on the cutting edge can't be cutting edge in every dimension. By all means sit back and watch from a distance. But these problems will certainly be fixed.
The enemy of this entire thesis is the layers of additional complexity required by such “innovation”. Each layer has its own API and update mechanisms, all of which slow down developer productivity (especially when inheriting a project you did not build).
In some cases that complexity is worth it — Figma, for example, squeezes a lot of value from WASM. I myself have used WASM to create a browser-based testing environment for a Rust-based static analysis tool I’ve built, so my colleagues can quickly repro issues. But for most web development, it’s not worth it.
My company did an initial evaluation of Rust web development just to see what the options were. Put out some feelers to our web developers to see if they had any opinions about it. It was almost universally negative. Not because the ecosystem or technology is immature, but because our JavaScript/Typescript devs simply could not grok Rust at all. It was too different, or too difficult, or whatever. So we didn't really pursue it any further. At some point though we'll probably just have to hire Rust engineers instead of trying to convert JS devs.
Rust on wasm is the same story as .net on wasm (aka blazor): it is nice if you have a single language developer workforce. But once you maintain a portal team, the benefit is gone.
IMHO, the more interesting niche is desktop/mobile apps using html as a toolkit. Because here you can combine raw computing/resource access with being more cross platform.
Neither one is a different language. Both merely add type annotations to an otherwise pristine ECMAScript code base.
Typescript has some very few and minor and no longer needed things, like enums or namespaces, that need to be transpiled and are not part of ECMAScript. But again, those are minor and you no longer need them (since ES 2015 one can use modules instead of namespaces, and marked "as const" object literals instead of enums).
I know some people want to argue definitions, "different language" etc., but it's really just a completely optional tooling layer that you can just strip. It's also evaluated purely during development time, for type checks, the actual code that gets executed remains the ECMAScript part.
Whenever there are changes in a new Typescript version it's either purely within the type system, or they add type support for new ECMAScript features, those proposals that reached stage 3.
You could just imagine the type annotations in a different layer than the actual code, like in Photoshop. A layer used only by the IDE and code checking tools.
Microsoft added greatly to the confusion by putting the type checker, like eslint usable standalone or continuously queried through the IDE, and the type annotation files (.d.ts) generation and the completely optional .js file transformation AND .js file transpilation - backwards compatible JS code for earlier runtimes - into one tool. But all of those are different things. If your traget is "esnext" or you don't use JS features that your target runtime does not yet support transpilation is just removal of type annotations (except, enums, namespaces, which are no longer necessary and only exist for historical pre ES2015 reasons).
As a recovered Haskell enthusiast, a can say that typescript is downright luxurious to work with for web development in a way that I think is hard to compete with in rust, because of how it types objects (like composable / decomposable sets), and the generic language to work with types really complements JavaScript instead of forcing you to do things differently.
This should be present tense, at least in the ClojureScript case.
Recent cool developments on that side include Electric Clojure - generating transparently state passing front and backend code from a single DSL: https://github.com/hyperfiddle/electric
The problem is not "bad code", but experience from teams and community. Browsing HN might make we think that Rust is everywhere and everyone knows it, but most of the frontend developers in the world are not prepared to inherit a project in such a foreign language.
My theory is that, you probably can see when a language its being picked by some community by looking into courses available, either free or on paid platforms
Engineering is a matter of tradeoffs. With JavaScript, you get simplicity but lose strict typing (can be compensated with TypeScript), performance etc. Rust gives you much better performance but is more complicated to write. However, for a lot of the websites out there, especially those that are not e-commerce or provide creative tools (e.g. Figma) and do not care that much about page performance, the potential performance gain from rewriting JavaScript code in Rust is not visible enough to end users. Of course there are bad websites out there that are slow, but it is often more about CDN/backend servers/the UI code itself rather than the JavaScript language. In other words, many websites are "fast enough", and most CTOs, product managers and developers would rather use JavaScript/TypeScript and release more features rather than write Rust, in the real world.
Same thing for a Rust replacement for VSCode -- I am sure it is an interesting project, but VSCode performance is generally good enough (I don't ever complain about slowness while developing). A lot of the performance bottleneck comes from the language services anyway. If you improve the loading speed from 2s to .2s that is definitely great, but if at the cost of losing most of the existing extensions, I'm not going to consider it at all.
Yes you can technically maybe get off the ground more quickly up front with JavaScript, but as soon as you hit a certain code base size threshold (not sure what it is personally, it is probably different case by case), you would've been better off with TypeScript or Rust as JavaScript starts to "crumble" under its own lack of types, etc.
> However, for a lot of the websites out there, especially those that are not e-commerce or provide creative tools (e.g. Figma) and do not care that much about page performance, the potential performance gain from rewriting JavaScript code in Rust is not visible enough to end user
Agreed. I would hate to see a CRUD spa written in Rust just because it was the fancy new thing. But sites like Figma, Miro, and Frame.io would make sense to look into a Rust WASM solution.
> but VSCode performance is generally good enough (I don't ever complain about slowness while developing).
The one thing I would say it can't handle is large files, like a large JSON file, I'm talking really large. It's something Sublime could handle and I used to keep it around just for that. This is not something I deal with often enough to really annoy me.
Javascript has pretty solid performance, assuming the code is half decent.
Honestly, a major benefit of strict/enforced type systems is that it substantially improves maintainability of the codebase. Large Python or JavaScript projects with no typing can be a huge nightmare.
This is probably true for the actual business application itself. It would be cool if we can get an ecosystem of performant WASM libraries that your JavaScript/TypeScript can use and be none the wiser.
IMO Rust is more expressive than most languages including languages like Python. Traits and enums are just... a joy to work with. It is also more constrictive in some ways, and a rust-like high-level language could do probably do better still (Swift/Kotlin/Elixir are close).
There's also a tradeoff between expressivity and performance and correctness. The way I see Rust is you get maybe 75% of the expressivity, along with much better performance and correctness guarantees.
I'd agree it's not a good fit for frontend, but IMO it's an excellent fit for backend.
That depends on what do you mean by expressive. I would call languages with more advanced type systems, like rust here, more expressive, as in allowing programmer to express his intention to both computer and other programmers clearer.
I believe that many people from Ruby on Rails and Django communities moved on to Clojure, Elixir, and Kotlin.
Others chose between Rust and Go, if performance was the most important thing.
The thing about dynamically typed languages and their expressiveness, is that you are sacrificing the ease of long-term maintenance for the ease of short-term prototyping.
Personally, I am a big fan of Clojure as a tool for designing software, but I would prefer having to maintain a code base written in Rust.
Even the maintainability argument is suspect I think: Static type systems as commonly used are not very powerful compared with schema validation style approaches used in the dynamic languages world (eg malli or spec in Clojure world). Static types lose in expressiveness, flexibility of when & where they are enforced, and ability to pass around the data shape specifications as data.
edit: and tangentially, the building and iterating lifecycle phase is of course usually the make-or-break bottleneck - maintenance phase sw engineering is comparatively a "happy problem".
You are not missing anything. I think people are going crazy for strict static typing because they want to feel like they're on the front edge of progress. But I don't think it's _better_; I think it's just _different_. I got bogged down in with Java and Angular awhile back. The amount of boilerplate required to keep the front end and back end compilers in sync was treacherous. Also, I had to make exceptions for corner cases that wouldn't match up. So it was no benefit to me. Maybe if your application is large enough that it involves big teams on each side, you would need static typing to keep everyone straight. And I think this is a large part of the back-and-forth on this forum. We discuss things that vary based on problem context without realizing (or admitting) that the implementation is situational.
I code alone and need performance for my project. I had choice beween C++ which I know a bit of; Go or Rust which I had to learn. Considering that I screw my mallocs and threads in C++ more often than not, I decided to check Rust. I am not disappointed: the safety helps a lot in getting my codebase free of many bugs (rust won't let me be lazy, I have to solve many bugs upfront). Sure the BC is madenning at times, but the support of the compiler allows me to not think too much about what I do and spend time on my business.
Now, on my old PC, the compiler is super slow so I end up prototyping tricky stuff (like maths) in python and then I port it to rust when I feel it's ready.
(my stuff is emulator: no DB, not much GUI but lots of performance, threading, etc.)
I disagree that you aren't missing "anything", there's no such thing as a free lunch. But I agree that _some_ of the uptick is because people are excited about being a "safe" and "rigorous" developer, but they get a nice package manager with Cargo that feels a lot like pip or npm.
I get a question over and over from front end devs when I teach or mentor about being a "real" computer scientist and picking up c, Cpp, or rust, which is silly. Who do you think invented the dynamically typed languages, English majors?
It makes more sense coming from the Rust side. For example, I can write a lightweight desktop app using the egui rust framework. But I can also compile that for the web, and run it in the browser. Basically for free, I just have to target wasm.
This also means that if you architect your app right, you have have the front-end and back-end self contained in the same app, or split them over a network boundary.
So let's say you are writing a 3d modeling app or something. You write the engine and the gui in rust, and you ship that binary to your users. You can then also, again basically for free, put a network between the gui and the rendering engine, then you can serve the gui to client browser, and handle the rendering on a server.
The point is this is easy for the rust dev, so they don't need to be a JavaScript dev as well.
"Compiled language" doesn't have to mean "much harder to read" though. I guess that's why many web devs like Go - it's a compiled language that feels more like a dynamic language because it tries to get the types out of the way as much as possible. Of course it doesn't have all the bells and whistles of Rust (now that generics were added, the next major complaint is nullability), but that's exactly what makes it easier to grok.
Both Python and Javascript are eating Rust's lunch in terms of popularity. And Typescript is just a typechecker, it's still a very dynamically typed language/runtime underneath.
Especially with Rust you have to think way more about banalities of the data model you normally really don't care about in web development.
Personally, I expected dynamic languages to ever match or at least get close to the performance of static languages. That seems that it will never happen, and there's a point where I can't afford that much hardware just to run a website. Think of Twitter abandoning RoR, etc.
In my view, JS is preferable because you are forced to ship source to the client.
This provides a beneficial atmosphere for learning and sharing solutions.
Compiling to WASM, and front-end builds in general, take this critical and unique quality away from the web platform.
Rust-to-WASM is another attempt to abstract away the pain of JavaScript, attempts which began soon after the world discovered XHR. In fact Google released GWT specifically to appeal to Java devs who took one look at JS and said "no thanks".
This is not so say that there aren't legit uses for this technology - its a great way to port other software, like sqlite or linux into the browser.
But as a way to make applications designed to run on the web?
I suggest that any dev that thinks this is necessary to have a good dev experience take the time to attempt to write a web app with just raw html, css, and js targeted at a modern browser.
There's a lot of space there left to explore, I think, before labeling it as an unwieldy thing that must be wrapped in a safer abstraction to even think of touching.
>Pretty much everything is bundled, minimized, and obfuscated now.
Yes, but there is a strain of software minimalism that eschews the front-end build entirely. This is relatively recently possible because of excellent implementations of relatively good standards starting with HTML5, CSS3, ES6, and SVG2.
I really, really can't wait for the extension to WASM to allow it direct access to the DOM and finally be able to remove the need for JS for 99% of its usage.
I do a lot of frontend development and I just cannot fathom how badly design JS as a language is and how awful the developer experience is. Every time I talk about JS shortcoming with other frontend dev, they point out that JS can do X or Y which other language cannot, but usually it is just a hack that are just not needed in other language because they actually do things properly (like having an actual sane type system and not having three ways to express that a variable is null). And TS is just a crutch that can barely help JS shortcoming.
Finally being able to compile from any language to a, reasonably sane, bytecode that can run in-place of JS is just a miracle and I don't understand why it took so damn long. JS should have been deprecated long ago. Even ActionScript was better.
JS can do some things very well that others can't. Prototype based reflection is very powerful!
Its problem is that the things Javascript excels at aren't all that useful, and the things it's bad at are often sold as features instead ("duck typing means I can iterate faster!").
Hum... Direct calling the DOM API is there already. You may be thinking about FFI marshaling, that there is something on the pipeline for helping (I don't even remember exactly what). But that's only a small improvement on speed, and that almost never is a dealbreaker.
For a while I thought the garbage collection helper was a dealbreaker (for anything except Rust), but GC languages are starting to compile into WASM too, with just a small performance hit. (I haven't looked exactly how.)
This year and the next are looking like some serious promising period for non-JS programing on the browser.
The biggest bottleneck in web applications was, is, and ever shall be, roundtrip time to the database, especially now that nobody bothers to install MySQL on the same box anymore, so every query has to go over the network. Of course, that's in a sane web application. Trendier approaches also try to shovel 10 MB of JavaScript over the wire first, so you can then call your API (which is slow for other reasons), and then render the result (which is also slow because you've shoveled 10 MB of JavaScript into the user's browser).
The language you choose matters relatively little.
I disagree, those 10MB of JS easily become 40MB of WASM. Picking a language that's compiled to Javascript for frontend code is the only good choice IMO.
WASM is not unlike the JARs and SWFs we got shoved down our throat ten years ago when HTML and JS were lacking any useful web capabilities. Huge files with separate runtime that implement their own renderer and operating environment. Google Docs already does this, using a canvas element to render to rather than using HTML and CSS to lay out text.
It's interesting to see Rust get up to speed in this realm, however I can't help but feel that so far, it's largely what I would call academically interesting. If I want to start a web project, I can hire a team of developers who know Javascript and its frameworks today. If some of them leave, I can rotate in other people with ease. Of course, this is a chicken and an egg problem, but for the time being it feels like a hard sell.
First CoffeeScript, then Flow and TypeScript, then ReasonML, and now Rust with WASM & web macros.
Of these only TypeScript has been successful, partly because it's backed by Microsoft, but mostly because the code you end up writing is very close to JavaScript.
This is not a dig at Rust (which I love) but God help any developer inheriting a frontend codebase with random bits of Rust in 2024.
It's not really that; it's really just WASM. There's going to be a flood of this sort of thing from all sorts of languages, even multiple per language. It's early days yet and the ground is still being felt out, but eventually the Javascript qua Javascript foundation in the browser is going to be breached and a day will come when it is a minority language (still many years from now), for exactly the same reason that never in the whole history of computing has one general purpose programming language "won". Per https://www.destroyallsoftware.com/talks/the-birth-and-death... , Javascript is going to "win", but it's going to be Javascript in its incarnation as WASM, not the Javascript we know today.
"random bits of Rust in 2024."
And that's "the ground being felt out", not a fundamental problem. I expect to see WASM frameworks develop that are shipped out to the world as WASM and bind to any language. Decent odds they'll be developed in Rust for several reasons (performance not least of all), but you won't need to know that to use it in your Python WASM front-end app or some new WASM-primary language that is nothing more than a gleam in its creator's eye right now. If you don't want the chaos, hey, great. Even people who live on the cutting edge can't be cutting edge in every dimension. By all means sit back and watch from a distance. But these problems will certainly be fixed.
In some cases that complexity is worth it — Figma, for example, squeezes a lot of value from WASM. I myself have used WASM to create a browser-based testing environment for a Rust-based static analysis tool I’ve built, so my colleagues can quickly repro issues. But for most web development, it’s not worth it.
IMHO, the more interesting niche is desktop/mobile apps using html as a toolkit. Because here you can combine raw computing/resource access with being more cross platform.
Dead Comment
Neither one is a different language. Both merely add type annotations to an otherwise pristine ECMAScript code base.
Typescript has some very few and minor and no longer needed things, like enums or namespaces, that need to be transpiled and are not part of ECMAScript. But again, those are minor and you no longer need them (since ES 2015 one can use modules instead of namespaces, and marked "as const" object literals instead of enums).
I know some people want to argue definitions, "different language" etc., but it's really just a completely optional tooling layer that you can just strip. It's also evaluated purely during development time, for type checks, the actual code that gets executed remains the ECMAScript part.
Whenever there are changes in a new Typescript version it's either purely within the type system, or they add type support for new ECMAScript features, those proposals that reached stage 3.
You could just imagine the type annotations in a different layer than the actual code, like in Photoshop. A layer used only by the IDE and code checking tools.
Microsoft added greatly to the confusion by putting the type checker, like eslint usable standalone or continuously queried through the IDE, and the type annotation files (.d.ts) generation and the completely optional .js file transformation AND .js file transpilation - backwards compatible JS code for earlier runtimes - into one tool. But all of those are different things. If your traget is "esnext" or you don't use JS features that your target runtime does not yet support transpilation is just removal of type annotations (except, enums, namespaces, which are no longer necessary and only exist for historical pre ES2015 reasons).
This isn’t really a matter of debate — Microsoft describes TypeScript as a programming language distinct from JavaScript on its homepage.
It’s a programming language with a trivial transpiration step to another language, but a separate language all the same.
Recent cool developments on that side include Electric Clojure - generating transparently state passing front and backend code from a single DSL: https://github.com/hyperfiddle/electric
No one is even close.
Why? Rust has a bunch of features built in to promote "good code", no?
My theory is that, you probably can see when a language its being picked by some community by looking into courses available, either free or on paid platforms
Same thing for a Rust replacement for VSCode -- I am sure it is an interesting project, but VSCode performance is generally good enough (I don't ever complain about slowness while developing). A lot of the performance bottleneck comes from the language services anyway. If you improve the loading speed from 2s to .2s that is definitely great, but if at the cost of losing most of the existing extensions, I'm not going to consider it at all.
Yes you can technically maybe get off the ground more quickly up front with JavaScript, but as soon as you hit a certain code base size threshold (not sure what it is personally, it is probably different case by case), you would've been better off with TypeScript or Rust as JavaScript starts to "crumble" under its own lack of types, etc.
JavaScript is like Legos, durable and you can build many things in it.
Agreed. I would hate to see a CRUD spa written in Rust just because it was the fancy new thing. But sites like Figma, Miro, and Frame.io would make sense to look into a Rust WASM solution.
> but VSCode performance is generally good enough (I don't ever complain about slowness while developing).
The one thing I would say it can't handle is large files, like a large JSON file, I'm talking really large. It's something Sublime could handle and I used to keep it around just for that. This is not something I deal with often enough to really annoy me.
Honestly, a major benefit of strict/enforced type systems is that it substantially improves maintainability of the codebase. Large Python or JavaScript projects with no typing can be a huge nightmare.
The pendulum has swung away from dynamic typing but are we sometimes sacrificing expressivity as a result?
I don't really know Rust but from what I've seen of it, it doesn't feel like a natural fit for the web - either front or back-end.
Maybe I'm missing something?
IMO Rust is more expressive than most languages including languages like Python. Traits and enums are just... a joy to work with. It is also more constrictive in some ways, and a rust-like high-level language could do probably do better still (Swift/Kotlin/Elixir are close).
There's also a tradeoff between expressivity and performance and correctness. The way I see Rust is you get maybe 75% of the expressivity, along with much better performance and correctness guarantees.
I'd agree it's not a good fit for frontend, but IMO it's an excellent fit for backend.
Others chose between Rust and Go, if performance was the most important thing.
The thing about dynamically typed languages and their expressiveness, is that you are sacrificing the ease of long-term maintenance for the ease of short-term prototyping.
Personally, I am a big fan of Clojure as a tool for designing software, but I would prefer having to maintain a code base written in Rust.
edit: and tangentially, the building and iterating lifecycle phase is of course usually the make-or-break bottleneck - maintenance phase sw engineering is comparatively a "happy problem".
Now, on my old PC, the compiler is super slow so I end up prototyping tricky stuff (like maths) in python and then I port it to rust when I feel it's ready.
(my stuff is emulator: no DB, not much GUI but lots of performance, threading, etc.)
I get a question over and over from front end devs when I teach or mentor about being a "real" computer scientist and picking up c, Cpp, or rust, which is silly. Who do you think invented the dynamically typed languages, English majors?
This also means that if you architect your app right, you have have the front-end and back-end self contained in the same app, or split them over a network boundary.
So let's say you are writing a 3d modeling app or something. You write the engine and the gui in rust, and you ship that binary to your users. You can then also, again basically for free, put a network between the gui and the rendering engine, then you can serve the gui to client browser, and handle the rendering on a server.
The point is this is easy for the rust dev, so they don't need to be a JavaScript dev as well.
I do think we'll see more simplicity (not Lisp-like) in the future.
Especially with Rust you have to think way more about banalities of the data model you normally really don't care about in web development.
Deleted Comment
Deleted Comment
It has a server side rendering mode, which for most projects will be all you need.
So then if you follow the Islands Architecture https://www.patterns.dev/posts/islands-architecture means you can sprinkle some typescript when you need more dynamic functionality.
I'd love to use Rust for front end enhancement in this way, but the problem is you have to completely open up your content security policy https://github.com/WebAssembly/content-security-policy/blob/...
Which is going to get picked up in any security review.
I've written up how I develop web apps with rust here https://rust-on-nails.com/
I wrote it up here https://rust-on-nails.com/docs/continuous-integration/integr...
Rust-to-WASM is another attempt to abstract away the pain of JavaScript, attempts which began soon after the world discovered XHR. In fact Google released GWT specifically to appeal to Java devs who took one look at JS and said "no thanks".
This is not so say that there aren't legit uses for this technology - its a great way to port other software, like sqlite or linux into the browser. But as a way to make applications designed to run on the web?
I suggest that any dev that thinks this is necessary to have a good dev experience take the time to attempt to write a web app with just raw html, css, and js targeted at a modern browser. There's a lot of space there left to explore, I think, before labeling it as an unwieldy thing that must be wrapped in a safer abstraction to even think of touching.
This hasn't really been true anymore for quite a long time. Pretty much everything is bundled, minimized, and obfuscated now.
Yes, but there is a strain of software minimalism that eschews the front-end build entirely. This is relatively recently possible because of excellent implementations of relatively good standards starting with HTML5, CSS3, ES6, and SVG2.
https://www.jslint.com/ is an example of what's possible with ES6 and built-in modules.
I do a lot of frontend development and I just cannot fathom how badly design JS as a language is and how awful the developer experience is. Every time I talk about JS shortcoming with other frontend dev, they point out that JS can do X or Y which other language cannot, but usually it is just a hack that are just not needed in other language because they actually do things properly (like having an actual sane type system and not having three ways to express that a variable is null). And TS is just a crutch that can barely help JS shortcoming.
Finally being able to compile from any language to a, reasonably sane, bytecode that can run in-place of JS is just a miracle and I don't understand why it took so damn long. JS should have been deprecated long ago. Even ActionScript was better.
Anyway, rant over.
Its problem is that the things Javascript excels at aren't all that useful, and the things it's bad at are often sold as features instead ("duck typing means I can iterate faster!").
Can you put breakpoints in WASM and debug frontend code?
Altering memory is more complicated, though.
Hum... Direct calling the DOM API is there already. You may be thinking about FFI marshaling, that there is something on the pipeline for helping (I don't even remember exactly what). But that's only a small improvement on speed, and that almost never is a dealbreaker.
For a while I thought the garbage collection helper was a dealbreaker (for anything except Rust), but GC languages are starting to compile into WASM too, with just a small performance hit. (I haven't looked exactly how.)
This year and the next are looking like some serious promising period for non-JS programing on the browser.
Why would i want to choose Rust? "Speed" and "not requiring as much of a memory footprint as well as more service uptime with less crashes".
I dunno man. I'm not saying those aren't interesting but I'm not sure that when it comes to web development that those are big hang ups.
There's got to be something more compelling IMO before you swing away from a fairly rich and frankly developer rich pool in JavaScript land...
Granted I enjoyed the article and my interest is piqued but that's it.
The language you choose matters relatively little.
WASM is not unlike the JARs and SWFs we got shoved down our throat ten years ago when HTML and JS were lacking any useful web capabilities. Huge files with separate runtime that implement their own renderer and operating environment. Google Docs already does this, using a canvas element to render to rather than using HTML and CSS to lay out text.
Deleted Comment