Video Trim
Blog

How a Video Editor Runs Inside Your Browser Tab

• Video Trim Team

Browser-based video tools that never upload your file sound implausible. Video encoding is heavy, low-level work, and JavaScript is not the obvious language for it. Here is how it actually works.

WebAssembly

WebAssembly, usually shortened to Wasm, is a low-level binary instruction format that browsers can execute at close to native speed. It is not a replacement for JavaScript; it is a compilation target. Code written in C, C++ or Rust can be compiled to Wasm and run in a browser tab.

This matters because decades of specialised software already exists in those languages. Rather than reimplement it in JavaScript, you compile what already works.

FFmpeg

FFmpeg is the open-source project that underpins a remarkable share of the world’s video handling. Media players, streaming pipelines, transcoding services and desktop editors all lean on it. It handles essentially every container and codec in common use, and it has been developed and hardened for over two decades.

Compiling FFmpeg to WebAssembly gives you that engine inside a browser tab. When you trim a video with a tool like this one, the operation being performed is broadly the one a command-line FFmpeg invocation would perform. It is the same library, running in a different place.

Why nothing gets uploaded

Browsers can read local files through the File API. When you choose a file, the page receives a handle to the data on your disk. It does not have to send that data anywhere; it can simply read it.

So the video data goes from your disk, into the browser’s memory, through the Wasm module, and back out as a new file the browser offers you as a download. There is no server in the path, because there is no step that requires one.

You can confirm this directly. Open developer tools, switch to the Network tab, and run a trim. You will see the page assets load, then silence. Load the page, disconnect from the internet, and the tool still works.

The memory constraint

The main limitation is memory. The Wasm module works in a linear memory space allocated by the browser, and video is large. Decoded frames are especially large: a single uncompressed 4K frame is roughly 24 MB, and processing requires several in flight at once.

Browsers cap how much a tab may allocate. In practice this means very large files can exhaust available memory where a desktop application, free to use disk as scratch space, would not.

This is why a browser tool may struggle with a two-hour 4K recording while handling a five-minute clip instantly. It is a memory ceiling, not a bandwidth or server limit.

Threading, and why the headers matter

Video encoding parallelises well, and FFmpeg uses multiple threads. In a browser, multi-threaded Wasm requires SharedArrayBuffer, which lets several workers access the same memory.

SharedArrayBuffer was restricted after the Spectre class of CPU vulnerabilities, because shared memory plus precise timers made those attacks easier. It was re-enabled only for pages that opt into strict isolation by sending two headers:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

These place the page in a state where it cannot freely share a process with other origins, or embed cross-origin resources that have not explicitly consented.

That is a genuine constraint. Third-party embeds, some analytics scripts and many ad tags do not send the required headers, so they break under require-corp. Browser-based media tools therefore often choose between multi-threaded speed and the ability to embed ordinary third-party content. Single-threaded Wasm works without the headers, and is slower.

What this architecture is good at

Speed for typical work, because there is no upload or download and no queue. Privacy, because the file genuinely never leaves the device. No file size limits imposed by a business model, since the operator pays nothing per video. Offline capability once loaded.

What it is not good at

Very long or very large files, because of the memory ceiling. Sustained heavy encoding on low-powered devices, where a server with a dedicated encoder would finish sooner. Anything genuinely requiring server-side resources, such as large model inference.

For trimming, cutting and format conversion, the trade lands clearly in favour of doing the work locally. The file is already on your device. Sending it around the world and back to remove ten seconds was never the efficient option.