zgba Network

Split PDF Pages in the Browser with pdf-lib — No Uploads, No Server

A few weeks ago I built a free online Merge PDF tool that runs 100% in the browser. Today I’m sharing its sibling: a Split PDF tool using the same library — pdf-lib — with zero file uploads, zero watermark, and zero server code. You can try it live here: https://yourutilityhub.com/pdf/split-pdf Why split PDFs in the browser? Most online PDF tools upload your file to a server — which means your document is never truly private. Splitting pages locally means: No uploads — nothing leaves your device No watermark or signup Free — no per-page charges Works offline, fast, for files of any size (limited by your browser’s memory) The plan We’ll load the PDF, pick a page range (or specific pages), copy those pages into a fresh PDFDocument, and save the result — all with pdf-lib. Let’s walk through the full working component. 1. Install and import npm install pdf-lib import { PDFDocument } from “pdf-lib”; 2. Load the uploaded file const arrayBuffer = await file.arrayBuffer(); const pdf = await PDFDocument.load(arrayBuffer); const totalPages = pdf.getPageCount(); PDFDocument.load() accepts an ArrayBuffer. We read it straight from the File object — no server involved. 3. Split by page range (e.g. 1-5 or 3-) const parts = pageRange.split(”-”); const startRaw = parseInt(parts[0].trim(), 10); const endRaw = parts[1].trim() === "" ? totalPages : parseInt(parts[1].trim(), 10); // validate 1..totalPages const startPage = Math.min(startRaw, endRaw) - 1; // 0-based const endPage = Math.max(startRaw, endRaw) - 1; const newPdf = await PDFDocument.create(); const pageIndices = []; for (let i = startPage; i <= endPage; i++) { pageIndices.push(i); } const copiedPages = await newPdf.copyPages(pdf, pageIndices); copiedPages.forEach(page => newPdf.addPage(page)); The trick: copyPages() wants 0-based indices, but users type 1-based page numbers, so we subtract 1. “3-” with an empty end means “to the last page.” 4. Or extract specific pages (e.g. 1,3,5) const pages = extractPages .split(”,”) .map(s => parseInt(s.trim())) .filter(n => !isNaN(n) && n > 0 && n <= totalPages); const newPdf = await PDFDocument.create(); const copiedPages = await newPdf.copyPages(pdf, pages.map(p => p - 1)); copiedPages.forEach(page => newPdf.addPage(page)); We parse comma-separated numbers, filter out anything out of range, then map to 0-based before copying. 5. Save, download, and clean up const pdfBytes = await newPdf.save(); const blob = new Blob([pdfBytes], { type: “application/pdf” }); const url = URL.createObjectURL(blob); const link = document.createElement(“a”); link.href = url; link.download = “split_” + file.name; link.click(); Blob + URL.createObjectURL() lets the user download the split file without the bytes ever touching a server. Full component The complete, production-ready React component (mode toggle, validation, error handling, and download) is live here: https://yourutilityhub.com/pdf/split-pdf The full source is also on GitHub: https://github.com/Jalal-khn/utilityhub- Caveats worth knowing copyPages reuses the existing page content — it does not re-parse fonts/images per page, so quality is preserved. Very large PDFs are limited by browser memory. For giant files, consider a server-side approach instead. The extracted pages keep their original dimensions and orientation. Why combine this with Merge PDF? Many users need both halves of the same workflow — split a big PDF apart, then merge specific pages back into one. Pairing them means users never have to send their documents to a third-party server for either task. Try it free: https://yourutilityhub.com/pdf/split-pdf

View original article