Merge and Split PDF Files Programmatically with pdf-lib
Merge multiple PDFs into one or split a PDF into pages using pdf-lib in Node.js. Pure JavaScript, no native binaries required. Working code examples included.
Manipulating PDF pages—combining multiple reports into a single file or extracting specific pages—can be performed entirely in pure JavaScript without external system dependencies like Poppler or Ghostscript using the pdf-lib library.
Installing pdf-lib
npm install pdf-lib
Download a multi-page 10MB PDF sample to test splitting and merging functions with pdf-lib.
Download 10MB PDF Sample →Merging Multiple PDFs
import { PDFDocument } from 'pdf-lib';
import fs from 'fs';
export async function mergePdfFiles(pdfBuffers: Buffer[]): Promise<Uint8Array> {
const mergedPdf = await PDFDocument.create();
for (const buffer of pdfBuffers) {
const donorPdf = await PDFDocument.load(buffer);
const copiedPages = await mergedPdf.copyPages(donorPdf, donorPdf.getPageIndices());
copiedPages.forEach((page) => mergedPdf.addPage(page));
}
return await mergedPdf.save();
}
Splitting a PDF (Extracting Page Ranges)
import { PDFDocument } from 'pdf-lib';
export async function extractPdfPages(
sourceBuffer: Buffer,
pageIndices: number[] // 0-indexed page numbers
): Promise<Uint8Array> {
const sourcePdf = await PDFDocument.load(sourceBuffer);
const newPdf = await PDFDocument.create();
const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);
copiedPages.forEach((page) => newPdf.addPage(page));
return await newPdf.save();
}
In-Memory Performance Tips
- Keep byte streams in memory: Avoid writing intermediary files to disk during multi-step merge operations.
- Preserve metadata: Use
mergedPdf.setTitle('Merged Report')andmergedPdf.setAuthor('My App')to maintain clean document properties.
Nguyen Dai Long
AuthorBackend Lead • Distributed Systems & Cloud Edge Architecture Specialist
4+ years designing high-throughput file ingestion pipelines, database architectures, and distributed edge storage on Cloudflare R2 & AWS S3. Founder of FileDummy and the NDL Ecosystem.
Was this article helpful?
Click Like to support the author and help other developers discover this guide.
Engineering Discussion & Feedback (0)
Share benchmark results, report edge cases, or ask technical questions.
No comments yet. Be the first developer to start the discussion!
Frequently Asked Questions
Does pdf-lib support password-protected PDFs?â–¾
pdf-lib can decrypt password-protected PDFs using the password option in PDFDocument.load(). The merged output is unencrypted by default. Re-encrypt with doc.encrypt() if required.
How do I merge large PDFs without running out of memory?â–¾
pdf-lib loads the entire PDF into memory. For very large PDFs (100MB+), use Ghostscript (gs -sDEVICE=pdfwrite -dBATCH -o merged.pdf input1.pdf input2.pdf) which processes pages in a streaming fashion.
Can I add page numbers when merging PDFs?â–¾
Yes. After copyPages(), use page.drawText() to add page numbers at any position. Embed a font first with doc.embedFont(). You can also add headers, watermarks, or bookmarks using the same drawing API.