DEV Community

Cover image for How I Built a File Converter That Never Touches Your Files published
Ahmer Arain
Ahmer Arain

Posted on

How I Built a File Converter That Never Touches Your Files published

I've used plenty of online file converters. Most of them upload your files to some server, process them, then (hopefully) delete them. You're trusting a stranger's backend with your documents, photos, or sensitive data.

I didn't love that. So I built ConvertifyHub — a file converter that supports 150+ formats and processes everything locally, right in your browser. Your files never leave your device.

Here's how I built it and what I learned along the way.


The Core Idea: Client-Side Everything

The whole product is built around one constraint: no file uploads, no server, no database.

That means every conversion — image, document, audio, video, archive — has to happen in the browser using JavaScript and WebAssembly. This is harder to build, but the payoff is massive:

  • Zero privacy risk for the user
  • No infrastructure cost for conversions
  • Instant processing (no round-trip to a server)
  • Works offline once loaded

The Stack

Frontend:   Next.js (TypeScript)
Deployment: AWS
Processing: Client-side JS + WebAssembly libraries
Enter fullscreen mode Exit fullscreen mode

No backend for file processing. No database. Just a fast frontend deployed on AWS.


How Each Tool Works Under the Hood

Image Conversion

For image conversion I use the browser's native Canvas API combined with libraries like sharp.js compiled to WebAssembly. The user drops a file, it gets read via FileReader, drawn to a canvas, then exported in the target format as a Blob.

const img = new Image();
img.src = URL.createObjectURL(file);
img.onload = () => {
  const canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  canvas.toBlob((blob) => {
    // Trigger download
    const url = URL.createObjectURL(blob);
    downloadFile(url, outputName);
  }, targetMimeType, quality);
};
Enter fullscreen mode Exit fullscreen mode

Audio & Video

This was the trickiest part. I used FFmpeg compiled to WebAssembly (@ffmpeg/ffmpeg). It's the same FFmpeg you'd run on a server — but running entirely in the browser via WASM.

import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';

const ffmpeg = createFFmpeg({ log: false });
await ffmpeg.load();

ffmpeg.FS('writeFile', inputName, await fetchFile(file));
await ffmpeg.run('-i', inputName, outputName);
const data = ffmpeg.FS('readFile', outputName);
Enter fullscreen mode Exit fullscreen mode

The file never leaves the browser. FFmpeg runs in a sandboxed WASM environment.

Archives

For ZIP/RAR/7Z handling I used JSZip and libarchive.js (another WASM port). Reading and creating archives purely in-browser.

Document Conversion

This one has limitations — true DOCX-to-PDF conversion server-side is always going to be more reliable. But for many use cases (txt, csv, basic formats) the browser handles it well.


The Tools I Ended Up Building

What started as "just an image converter" turned into a full suite:

  • Image Converter — 25+ formats including WebP, AVIF, HEIC
  • Image Resizer & Compressor
  • Audio Converter — MP3, WAV, FLAC, AAC, OGG (via FFmpeg WASM)
  • Video Trimmer
  • Document Converter
  • Archive Converter — ZIP, RAR, 7Z, TAR
  • Spreadsheet Converter — XLSX, CSV, TSV
  • Unit & Digital Converters — 50+ units, number bases, color formats
  • QR & Barcode Generator
  • Code Minifier & Beautifier
  • Font Converter — TTF, OTF, WOFF, WOFF2
  • Security Tools — JWT, hashing, encryption utilities
  • JSON → TOON Converter — for LLM token optimization
  • Website Image Scraper
  • SVG Optimizer
  • Markdown Converter

That's 20+ tools, all running client-side.


What Made This Hard

1. WebAssembly Loading Time

FFmpeg WASM is ~25MB. First load is slow. I lazy-load it only when the user actually needs audio/video conversion, and show a progress indicator.

2. Memory Limits

Browsers cap memory. Large files (especially video) can crash the tab. I added file size warnings and chunk large files where possible.

3. Format Support Gaps

Not every format has a good JS/WASM library. HEIC on some browsers is still a pain. I had to pick my battles and clearly communicate unsupported edge cases.

4. Cross-Browser Consistency

Canvas API behaves differently across browsers for certain image formats. Lots of testing across Chrome, Firefox, Safari.


The Privacy-First Architecture

No file uploads means:

  • No S3 buckets storing user files
  • No database needed
  • No GDPR headaches around file storage
  • No server costs per conversion

The only infra I run is serving the Next.js frontend on AWS. That's it.


What's Next

  • More batch processing support
  • Better progress indicators for large files
  • PWA support for offline use
  • More AI-assisted format recommendations

Try It

👉 convertifyhub.net

No account needed. No upload. Just drop a file and convert.

If you're building something privacy-sensitive and wondering whether you can move processing to the client — in many cases, you can. WebAssembly has made things possible in the browser that used to require a backend. I'd love to hear if you've taken a similar approach.

Drop a comment if you have questions about any part of the stack!


About the Author

Ahmer Arain — Full-stack developer specializing in MERN stack, Next.js, and AWS. I build scalable web and mobile products, from SaaS platforms to marketplace apps.

🌐 ahmerarain.com
💼 linkedin.com/in/ahmer-arain
🐙 github.com/ahmerarain
📧 ahmerarain18@gmail.com

Top comments (0)