HomePDF ToolsPDF Merge

multiple pdfs. one file.

merge multiple PDF files into one document. drag to reorder. 100% client-side — your files never leave your browser.

drop PDFs here

or click to browse — up to 10 files

choose files

PDF

your files never leave your browser

What this tool actually does

Drop two or more PDFs in, drag them into the order you want, hit merge, and you get back a single combined PDF. The whole operation runs in your browser — your files never reach a server, because there isn't one in the loop. The merged file is generated locally and downloaded directly from the tab you have open.

That is the entire user-facing description. The rest of this page is for people who want to know why it works that way, and what it does and does not handle.

How a PDF merge works under the hood

A PDF is a structured binary container. Every page lives as an object inside the file, and the document keeps a tree (the /Pages tree) that lists which pages belong to the document and in what order. Merging two PDFs is not about gluing bytes together — it is about copying pages from each source document into a new /Pages tree.

Persimmon uses pdf-lib for the structural work. The actual merge logic looks roughly like this:

typescript
import { PDFDocument } from "pdf-lib";

async function mergePdfs(files: File[]): Promise<Blob> {
  const out = await PDFDocument.create();

  for (const file of files) {
    const bytes = await file.arrayBuffer();
    const src = await PDFDocument.load(bytes);
    const pages = await out.copyPages(src, src.getPageIndices());
    pages.forEach((p) => out.addPage(p));
  }

  const merged = await out.save();
  return new Blob([merged], { type: "application/pdf" });
}

copyPagesis the important call. It clones every page object the source references — including embedded fonts, images, annotations, and form fields — into the destination's object table. The result is a structurally valid new PDF, not a stitched-together hybrid.

What gets preserved, and what does not

Preserved across a merge:

  • Page content (text, images, vector graphics) bit-for-bit.
  • Embedded fonts, including subsetted ones.
  • Hyperlinks within a page.
  • Form fields (in most cases).
  • Page rotation and crop boxes.

Things that can get tricky:

  • Internal cross-document links.A link in source A pointing at “page 17 of source A” will continue to work after merge, but a link in source A pointing at source B by file name will not — there is no source B anymore as a separate file.
  • Bookmarks / outlines. pdf-lib does not currently merge outline trees, so the combined file may end up with no bookmarks even if the originals had them. If your reader depends on bookmarks for navigation, this is a real limitation.
  • Encrypted source files. If a source PDF is password-protected, the merge will fail until you unlock it first. The tool does not attempt to crack or remove encryption.

The privacy reason this is a browser-only tool

Most PDFs you handle in any given month are sensitive: signed contracts, scanned IDs, tax forms, medical bills, leases. The default model for online merging is to upload your file to a server you have never heard of, run the merge there, and trust the operator to delete it on schedule. There is no way to verify the deletion happened — or that the file did not end up in a backup, cache, or analytics pipeline along the way.

The check you can run yourself

Open DevTools, go to the Network tab, and run a merge here. You will see exactly zero outbound requests carrying your PDF as a payload. The whole operation is local. If you ever do see one, that is a bug we want to know about.

We wrote a longer piece on the architectural reasoning behind this: Why every PDF tool on Persimmon runs in your browser.

The honest limitations

File size

Browser memory is real and finite. A typed array in a single page caps around 2GB on most browsers, and practical performance degrades well before that. For typical document workflows (contracts, scans, reports under a few hundred MB) this is a non-issue. For archival merges of multi-GB files, you will hit a wall.

OCR and searchable text

If your source PDFs are scans without a text layer, the output will also have no text layer — merging does not perform OCR. We do not currently offer client-side OCR because the available WebAssembly OCR runtimes are slow and inaccurate compared to purpose-built services.

Compression

The merge does not re-encode or recompress page contents. If your sources have large embedded images, the merged file size will be roughly the sum of the inputs. If you need a smaller output, run the result through a PDF compression tool afterward.

Common workflows this handles well

  • Combining individually scanned pages back into a single document.
  • Bundling a cover letter, contract, and addendum into one file for signing.
  • Merging quarterly reports for tax filing or board packets.
  • Assembling a portfolio from per-project PDFs.
  • Joining the pages of a multi-part scan that came out as separate files.

For the inverse operation — pulling specific pages out of a PDF into separate files — see the PDF split tool. For converting a merged PDF into a sequence of images for embedding elsewhere, the PDF to images tool handles that without a server either.

What this tool actually does

Drop two or more PDFs in, drag them into the order you want, hit merge, and you get back a single combined PDF. The whole operation runs in your browser — your files never reach a server, because there isn't one in the loop. The merged file is generated locally and downloaded directly from the tab you have open.

That is the entire user-facing description. The rest of this page is for people who want to know why it works that way, and what it does and does not handle.

How a PDF merge works under the hood

A PDF is a structured binary container. Every page lives as an object inside the file, and the document keeps a tree (the /Pages tree) that lists which pages belong to the document and in what order. Merging two PDFs is not about gluing bytes together — it is about copying pages from each source document into a new /Pages tree.

Persimmon uses pdf-lib for the structural work. The actual merge logic looks roughly like this:

typescript
import { PDFDocument } from "pdf-lib";

async function mergePdfs(files: File[]): Promise<Blob> {
  const out = await PDFDocument.create();

  for (const file of files) {
    const bytes = await file.arrayBuffer();
    const src = await PDFDocument.load(bytes);
    const pages = await out.copyPages(src, src.getPageIndices());
    pages.forEach((p) => out.addPage(p));
  }

  const merged = await out.save();
  return new Blob([merged], { type: "application/pdf" });
}

copyPagesis the important call. It clones every page object the source references — including embedded fonts, images, annotations, and form fields — into the destination's object table. The result is a structurally valid new PDF, not a stitched-together hybrid.

What gets preserved, and what does not

Preserved across a merge:

  • Page content (text, images, vector graphics) bit-for-bit.
  • Embedded fonts, including subsetted ones.
  • Hyperlinks within a page.
  • Form fields (in most cases).
  • Page rotation and crop boxes.

Things that can get tricky:

  • Internal cross-document links.A link in source A pointing at “page 17 of source A” will continue to work after merge, but a link in source A pointing at source B by file name will not — there is no source B anymore as a separate file.
  • Bookmarks / outlines. pdf-lib does not currently merge outline trees, so the combined file may end up with no bookmarks even if the originals had them. If your reader depends on bookmarks for navigation, this is a real limitation.
  • Encrypted source files. If a source PDF is password-protected, the merge will fail until you unlock it first. The tool does not attempt to crack or remove encryption.

The privacy reason this is a browser-only tool

Most PDFs you handle in any given month are sensitive: signed contracts, scanned IDs, tax forms, medical bills, leases. The default model for online merging is to upload your file to a server you have never heard of, run the merge there, and trust the operator to delete it on schedule. There is no way to verify the deletion happened — or that the file did not end up in a backup, cache, or analytics pipeline along the way.

The check you can run yourself

Open DevTools, go to the Network tab, and run a merge here. You will see exactly zero outbound requests carrying your PDF as a payload. The whole operation is local. If you ever do see one, that is a bug we want to know about.

We wrote a longer piece on the architectural reasoning behind this: Why every PDF tool on Persimmon runs in your browser.

The honest limitations

File size

Browser memory is real and finite. A typed array in a single page caps around 2GB on most browsers, and practical performance degrades well before that. For typical document workflows (contracts, scans, reports under a few hundred MB) this is a non-issue. For archival merges of multi-GB files, you will hit a wall.

OCR and searchable text

If your source PDFs are scans without a text layer, the output will also have no text layer — merging does not perform OCR. We do not currently offer client-side OCR because the available WebAssembly OCR runtimes are slow and inaccurate compared to purpose-built services.

Compression

The merge does not re-encode or recompress page contents. If your sources have large embedded images, the merged file size will be roughly the sum of the inputs. If you need a smaller output, run the result through a PDF compression tool afterward.

Common workflows this handles well

  • Combining individually scanned pages back into a single document.
  • Bundling a cover letter, contract, and addendum into one file for signing.
  • Merging quarterly reports for tax filing or board packets.
  • Assembling a portfolio from per-project PDFs.
  • Joining the pages of a multi-part scan that came out as separate files.

For the inverse operation — pulling specific pages out of a PDF into separate files — see the PDF split tool. For converting a merged PDF into a sequence of images for embedding elsewhere, the PDF to images tool handles that without a server either.

more free tools

PDF utilities, image tools, developer helpers — all free, no signup.

Something wrong?