The Problem with "Free Online PDF Merger"
Search "merge PDF" and you'll get a wall of sites that look professional. Drag your files in, get a merged PDF out. Simple.
But pause for a second on what just happened.
You took two documents — maybe a signed contract and an invoice, maybe a tax form and a bank statement — and shipped them to a server you've never heard of, in a country you can't name, run by a company whose privacy policy you didn't read.
The merged file came back to you in fifteen seconds. The original files are still on that server. Probably for "performance reasons" or "to improve our service." Maybe they get deleted after 24 hours like the policy says. Maybe.
You can do better. The browser already has everything needed to merge PDFs locally. No upload required.
The Two-Click Way
Open aayushali.com/tools/merge-pdf. Drag your files into the upload zone. Click the merge button. Download.
That's the whole thing. The files never leave your computer. There's no account, no email, no watermark, no page limit, no file size limit beyond what your browser can handle in memory (which is generous — I've merged 200MB of PDFs without issue).
If you're skeptical, open DevTools, switch to the Network tab, and watch as you process files. You'll see exactly zero requests carrying your PDF data. The only network call is for the page itself.
Why This Works at All
PDF is just a file format. It's well-documented and parseable in JavaScript. There's a library called pdf-lib that reads and writes PDFs entirely client-side.
Here's roughly what happens when you merge two files:
import { PDFDocument } from 'pdf-lib'
const merged = await PDFDocument.create()
for (const file of files) {
const bytes = await file.arrayBuffer()
const pdf = await PDFDocument.load(bytes)
const pages = await merged.copyPages(pdf, pdf.getPageIndices())
pages.forEach(page => merged.addPage(page))
}
const finalBytes = await merged.save()
That's the entire merge operation. Twelve lines. No server. No upload. Modern browsers can run this on multi-hundred-megabyte files without breaking a sweat.
The tool on my site wraps this with a drag-and-drop interface, a page reorder UI, and a download button. That's the value add. The actual PDF logic is open and well-tested.
When You Should Use a Local Tool (Always)
You should never upload PDFs to a random website if you have a local option. The categories of files where this matters most:
- Anything with your address, ID number, or signature — driver's licenses, passports, leases
- Financial documents — bank statements, tax returns, pay stubs
- Medical records — test results, prescriptions, insurance forms
- Work documents — contracts, NDAs, employee handbooks
- Legal papers — basically anything from a lawyer
For each of these, the worst-case scenario of "this PDF leaks publicly" ranges from embarrassing to genuinely harmful. The convenience of a five-second merge is not worth the risk.
Local processing isn't paranoia. It's the obvious default once you know it exists.
What About Mac Preview or Adobe?
If you're on a Mac, Preview can merge PDFs natively. Drag pages from one document onto another in the sidebar. It works.
But three things annoy me about it:
- The UI is hidden behind the page thumbnail sidebar, which most people don't have open
- It can't reorder mid-merge as easily as a dedicated tool
- You can't do it on a Windows machine, a Chromebook, or a phone
Adobe Acrobat does it too, of course, if you pay $14.99/month. Which is a lot of money for "occasionally combine two PDFs."
A browser tool sidesteps all of this. Works on every OS. Works on mobile. Costs nothing. Same privacy guarantees as a native app.
Try It
The merge tool lives here: aayushali.com/tools/merge-pdf.
It's part of a small collection of browser-based PDF tools I built because I was tired of the alternatives. There's also a splitter, a compressor, a rotator, and a full editor for adding text, drawing, and signing.
All of them work the same way. Drag your file in. Do the thing. Download. The file never leaves your machine.
That's how this should have always worked.