DEV Community

Eduardo Keser
Eduardo Keser

Posted on

Merging PDFs in the browser without uploading anything: what I learned building a free tool for Argentine paperwork

Most "merge PDF" sites ask you to upload your files to a server. That's fine for a menu, but not for a scan of your ID or a payslip. When I built Trámite Listo (a free set of PDF tools for Argentine paperwork), I made one rule: the files never leave the user's device.

Here's how it works and what bit me.

The stack

  • pdf-lib to create and modify PDFs (merge, split, rotate, images to PDF, remove pages).
  • pdf.js to read and render pages when I need to see them.
  • JSZip to bundle several outputs into one download.
  • jsdiff to compare two documents.

No backend processes files. The site is static HTML and JS.

Merging, in a few lines

The core idea is to load each PDF, copy its pages into a new document, and save:

const out = await PDFLib.PDFDocument.create();
for (const file of files) {
  const bytes = await file.arrayBuffer();
  const src = await PDFLib.PDFDocument.load(bytes);
  const pages = await out.copyPages(src, src.getPageIndices());
  pages.forEach(p => out.addPage(p));
}
const merged = await out.save();           // Uint8Array
const url = URL.createObjectURL(new Blob([merged], { type: 'application/pdf' }));
Enter fullscreen mode Exit fullscreen mode

Everything happens in memory in the user's tab, and the download is a Blob URL.

Things that bit me

  1. Memory is the real limit. Large PDFs are limited by the user's device, not by my server. I say so on the page ("works with files up to about 100 MB, depending on your device's memory") instead of promising more.
  2. Encrypted or damaged PDFs. load can throw. I show a plain message instead of failing silently.
  3. Phones. Many people in my country do paperwork from a phone, so the UI has to work with a file picker and without drag-and-drop.
  4. Trust has to be visible. A line saying "100 % private: files are processed on your device" next to the upload box did more than any technical explanation.

Bonus: a deadline calculator with moving rules

The same site has a calculator for legal deadlines that accounts for national and provincial holidays. The surprise: the code is easy, the data keeps moving. A new decree can add a holiday overnight, so I cite the official source for every rule and re-check it regularly.

Try it / feedback

It's free, available in Spanish and English, and has no signup: https://edydigital.online

I'd love feedback from anyone who has built client-side file tools: what limits did you hit, and how do you handle very large files? I wrote this post myself.

Top comments (0)