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 split page keeps its rotation via setRotation.
What I deliberately left out
No accounts. Nothing to phish, nothing to leak, nothing to manage.
No analytics. I don't know how many people use it, and I'm fine with that.
No paid tier. No watermarks on free output, no "upgrade to merge more than 5 pages."
No "AI features." I considered adding "summarize this PDF" and decided no. It would require either a server (defeats the purpose) or running a model in the browser (heavy, and most users don't want it). The tool does one thing well.
Limits, honestly stated
Client-side has real constraints:
Memory. A 500-page PDF will strain a mobile browser. I cap at 50 pages on mobile, 200 on desktop, and warn instead of silently truncating.
Encrypted PDFs. pdf-lib loads them with ignoreEncryption: true, but if they're actually password-protected, rendering fails gracefully (the thumbnail shows "Render failed" and the page is skipped, never a crash).
No OCR. If you need text extraction from scanned images, this isn't the tool. That's a server-or-model problem.
Try it
The code is on GitHub: https://github.com/JeffreyHamilton6399/MergePDF. It deploys to Vercel with zero environment variables — import the repo, click deploy, you're done.
If you build something with it, or find a bug, I'd love to hear about it. And if this is the kind of tool you'd rather use than the one that uploads your tax returns — well, that's the whole point.
If you found this useful, I write about client-side web stuff and don't have a newsletter to plug. I do have a Buy Me a Coffee if you're feeling generous.
Top comments (0)