WebAssembly: why the browser now does things that used to need an installed program
Editing video or compressing a PDF inside a browser tab stopped being impossible only a few years ago. The reason has a name, and understanding it explains why so many websites changed architecture at once.
In 2015, if you wanted to trim a video you had two options: install a program, or upload the file to a website that would do it on its own server. There was no third choice.
Now there is. You can trim that video inside a browser tab, without installing anything and without the file ever leaving your computer. The shift wasn’t gradual and it wasn’t a JavaScript improvement. It was a new piece arriving: WebAssembly.
The problem JavaScript couldn’t solve
JavaScript was born in 1995 for small jobs: validating a form, opening a menu. Nobody designed it to decode video.
Over the years it became remarkably fast. Modern engines do just-in-time compilation and optimisations that once seemed impossible. But it carries two traits that can’t be removed without breaking the entire web:
It’s dynamically typed. A variable can hold a number and, a moment later, a string. The engine has to keep checking at runtime, and those checks cost. A language where types are known ahead of time skips that work entirely.
It doesn’t control memory. JavaScript is garbage collected: it decides on its own when to free memory. That’s convenient to program against, but it introduces unpredictable pauses. When you’re processing video frame by frame, those pauses add up.
The result was a ceiling. You could write a video decoder in JavaScript — people did — but it ran five to twenty times slower than the same algorithm compiled. Slow enough to be unusable.
What WebAssembly actually is
WebAssembly is not a programming language. It’s a binary instruction format that browsers know how to execute, designed as a compilation target for other languages.
You write C, C++ or Rust. The compiler produces a .wasm file. The browser runs it at close to native speed.
Three design decisions explain why it works:
It’s binary and compact. There’s no text to parse: the browser can start compiling while the file is still downloading.
It’s statically typed. Every operation knows what it’s working with before it runs. No runtime checks.
Memory is a flat block. The program gets an array of bytes and manages it itself, exactly as a native program would. No garbage collector interfering.
The practical consequence is enormous: existing code could be reused. Libraries written twenty years ago, debugged by thousands of people, were recompiled to WebAssembly without being rewritten. FFmpeg, which moves essentially all the video on the internet, now runs inside a tab as the same code it always was.
What changed in practice
Before WebAssembly, any heavy task forced this architecture:
Your file → network → server → processing → network → your file
That means servers somebody pays for, upload and download time, size limits, queues at peak hours, and a copy of your file on someone else’s computer.
With WebAssembly the architecture collapses to:
Your file → browser memory → processing → your downloads folder
Processing servers, transfer time and the remote copy all disappear. And something new appears: the tool keeps working offline once the page has loaded.
Where WebAssembly is today
You may already have used it without knowing:
| Application | What WebAssembly does |
|---|---|
| Figma | The canvas rendering engine |
| Photoshop and Lightroom web | The image editing core, ported from C++ |
| Google Earth | 3D rendering in the browser |
| AutoCAD web | The drawing engine, decades of C++ behind it |
| Conversion tools | FFmpeg, libvips and PDF libraries, compiled |
The pattern repeats: applications with large, mature native codebases that wanted to reach the browser without rewriting from scratch.
The limits, which are real
WebAssembly isn’t magic, and it’s worth knowing what it doesn’t do.
It has no direct browser access. It can’t touch the DOM, make a network request, or read a file on its own. All of that goes through JavaScript acting as an intermediary. That crossing has a cost, so the sensible architecture is to hand over one large chunk of work and collect the result, not to call across a thousand times in a row.
It isn’t automatically faster. For interface logic and page manipulation, JavaScript usually wins: it’s heavily optimised for exactly that and doesn’t pay the crossing toll. WebAssembly shines at sustained heavy computation.
Modules are big. A compiled FFmpeg runs to tens of megabytes. It’s downloaded once and cached, but the first visit feels it. Well-built tools load the engine only when you’re about to use it, not on page load.
It’s inside the same sandbox. It can’t read your documents or reach the system. It only sees what you explicitly hand it. That’s a design limitation, and also the reason it’s safe to run.
Multithreading: the awkward part
WebAssembly can use multiple cores, which multiplies speed on parallelisable work. But it needs SharedArrayBuffer, and that object was restricted after the Spectre vulnerabilities in 2018.
To enable it, a site must send two headers that turn on cross-origin isolation. And that isolation blocks any external resource that doesn’t explicitly opt in: fonts, images from other domains, embedded video and — very notably — advertising iframes.
It’s an awkward and little-known trade-off: a site can have multithreaded WebAssembly or advertising, but not both on the same page. Most online tools pick single-threaded mode, which is slower but doesn’t break the rest of the site.
Where it’s heading
Three pieces on the way matter:
WASI, for running WebAssembly modules outside the browser, on servers, with millisecond cold starts.
Garbage collection, which will let languages like Java, C# or Kotlin compile comfortably without shipping their own memory manager.
The component model, so modules written in different languages can call each other with high-level types instead of raw bytes.
The takeaway
WebAssembly didn’t come to replace JavaScript, and it won’t. It came to fill the gap JavaScript could never fill: heavy computation at native speed.
Its most visible effect for an ordinary user is simple. Tasks that required installing software or uploading files to a server now fit in a browser tab. That’s not a minor technical detail: it changes who has your files, and what you need to install to work with them.