I built a PDF merger that never uploads your files — here's how published: false
MergePDF is a 100% client-side PDF tool. No backend, no uploads, no sign-up. Here's the architecture, the tricky parts, and why privacy is a feature, not a setting. Every tax season, the same thing happens. Someone in my family asks me to merge a few PDFs. They Google "merge PDF." They click the first result — a slick, friendly-looking site. They upload their tax returns to a server they've never heard of. That bothered me. So I built MergePDF. It merges, splits, rotates, and rearranges PDF pages — and your files never leave your browser. No backend. No sign-up. No ads. No tracking. iLovePDF uploads your tax returns. We don't. This post is about how it works, the parts that were harder than I expected, and why "client-side only" is a design philosophy, not just a technical choice. The pitch in 30 seconds Drop one or more PDFs onto the page. You get a grid of page thumbnails — real, rendered previews of every page. Drag to reorder. Click to select. Rotate, delete, extract a range. Merge everything into one file, or split into single-page PDFs zipped up. Download. Done. Your browser does all of it. There is no server processing documents. There isn't even a server to process documents. The stack It's a Next.js app, but honestly Next.js is just the host here. The interesting parts are all client-side libraries doing real work: No database. No API routes. No auth. No analytics. The only thing in localStorage is your theme preference. Drag-to-reorder that doesn't fight tap-to-select This one took three attempts. The requirement: Tap a thumbnail → select it (emerald ring) Shift-tap → select a range Long-press + drag → reorder Swipe on mobile → scroll the grid (don't drag) The conflict: if the whole card is the drag handle, taps get swallowed. If only a tiny grip icon is the handle, nobody finds it (especially on mobile, where there's no hover). So split produces a ZIP. fflate's zip packages every single-page PDF into one download. Rotations are honored here too — each spl