DEV Community

Cover image for Zero-Server Video & Image Conversion: Harnessing WebAssembly for Client-Side HEIC/MOV Processing
ludy.dev
ludy.dev

Posted on • Originally published at iosconvert.com

Zero-Server Video & Image Conversion: Harnessing WebAssembly for Client-Side HEIC/MOV Processing

Featured Image

As an indie developer, one of my biggest everyday pet peeves is trying to share files between my iPhone and non-Apple devices. Apple’s proprietary formats—namely HEIC for photos and MOV for videos—are fantastic for storage efficiency on iOS, but they are a massive headache to open, edit, or upload anywhere else.

Normally, you'd head to an online conversion site, upload your private photos, wait for a server to process them, and download them. But as a developer, this workflow screamed three major red flags: user privacy risks, slow upload/download bottlenecks, and massive backend server costs for the creator.

I wanted to build a tool that solves this entirely within the browser. The result is iosconvert.com. Here is how I engineered a 100% client-side, zero-server converter using WebAssembly and modern browser APIs.

The Technical Challenge: Decoding HEIC in Javascript

Browsers cannot natively decode HEIC files. To render or convert them, we need a decoder. Building a decoder in raw JavaScript would be incredibly slow and inefficient.

To solve this, I compiled libheif (a widely used C++ library for HEIF files) into WebAssembly (WASM) using Emscripten. When a user drops a .heic file onto the browser:

  1. The file is read as an ArrayBuffer.
  2. The WASM module parses the buffer and extracts the raw RGB pixel data.
  3. The pixel data is written directly to an OffscreenCanvas.
  4. The canvas exports the image as a standard JPEG or PNG blob.

By leveraging Web Workers, this entire heavy-lifting process happens on a background thread, keeping the main UI thread completely responsive at 60 FPS.

Taming Video: MOV to MP4 Without the Overhead

Converting video is a different beast. Standard FFmpeg compiled to WASM (ffmpeg.wasm) is incredibly powerful, but it comes with a massive 30MB+ payload. Forcing a mobile user to download a 30MB framework just to convert a 5-second video is a terrible user experience.

Since most iPhone MOV files already use standard H.264 or HEVC codecs, we don't actually need to re-encode the entire video stream. Instead, we can perform container swapping (demuxing and remuxing). By parsing the MP4/MOV container structure in JavaScript, we can extract the raw video and audio tracks from the MOV container and pack them into a standard MP4 container in milliseconds—bypassing CPU-heavy transcoding entirely.

Scaling to Millions of Users for $0/Month

Because 100% of the computing power is offloaded to the user's browser, the server costs for the site are literally zero. The entire frontend is a static React application hosted on a global CDN.

More importantly, it’s a massive win for user privacy. Since no files are ever uploaded to a remote server, user data never leaves their local machine.

I'd love to get your feedback on the architecture! Try converting a few of your own Apple files at iosconvert.com and let me know how the client-side performance holds up on your machine.

Top comments (0)