Split PDF
Split a PDF into multiple files by page range, every N pages, or one PDF per page — fully inside your browser, no signup, no upload. Each output keeps the original pages byte-identical; nothing is re-rasterised. Sources cited.
How it works
A PDF file is, in spec terms, a body of numbered objects (pages, fonts, images, content streams) plus a cross-reference table that tells a reader the byte offset of each object. The page tree (ISO 32000-2 §7.7.3.2) is a shallow structure: a root /Pages dictionary points to /Kids (each a /Page object), and the catalog points to that root. To split a PDF you copy a subset of the page objects — together with everything they reference (fonts, images, resources, content streams) — into a fresh document and rebuild a single page-tree root over the lot. That is what this tool does for every output range.
The split is performed by pdf-lib, an MIT-licensed pure-JavaScript PDF library. It is loaded dynamically when you press Split — until then the page bundle stays small and your browser does not download the ~270 KB library. Inside the React component the flow is straight: PDFDocument.load(bytes) for the source, then for each output range a fresh PDFDocument.create() plus copyPages(src, [i..j]).addPage(...), and finally save() to serialise each output.
Before any pdf-lib work runs the tool does four deterministic things so the plan can be validated up front:
- Validate the source. Confirms the PDF MIME type, a non-zero size, and a per-file cap of 100.0 MB. The first 1 KB is scanned for the literal
%PDF-n.mheader (ISO 32000-2 §7.5.2), and the last 2 KB for the%%EOFterminator (§7.5.5). Files missing either are rejected with an explanation. - Read the exact page count. pdf-lib parses the catalog and page tree and reports
getPageCount(). That number is the ceiling for every range the user enters — an out-of-bounds range becomes an inline error before the split runs. - Build a plan. The selected mode produces a list of output ranges. By-range mode parses the text expression; every-N mode walks
for (start = 1; start ≤ total; start += N); each-page mode produces N ranges of one page each. Plans are capped at 500 output files. - Cross-check the plan. The plan is summed two ways. First by arithmetic (
end − start + 1, totalled), then by independent enumeration (a nested loop that adds 1 per page visited). The two totals must agree and every page must lie inside the source. If anything is off, the Split button is disabled with a specific error. - Run the split. For each range, pdf-lib creates a destination document, copies the selected pages (preserving the original byte streams), writes a fresh catalog and trailer, and returns the merged byte buffer. Each buffer is wrapped in a Blob, exposed via an object URL, and offered to you as a download. No bytes leave the browser tab.
Worked examples
Frequently asked questions
Sources & references
- ISO 32000-2 — PDF 2.0 specification (file header §7.5.2, trailer §7.5.5, page tree §7.7.3.2, object streams §7.5.8)
- pdf-lib — MIT-licensed pure-JavaScript PDF library used for the page-tree surgery
- pdf-lib source on GitHub (open-source, audited)
- MDN — File API (used for in-browser file reads, no upload)
The PDF header, trailer, and plan integrity validators were cross-checked against ISO 32000-2 on 2026-05-11. The pdf-lib dependency is pinned in package.json and re-verified on each major-version bump.
Related tools
Comments & feedback
Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.
Found a bug, edge case, or want to suggest an improvement?
Email me at [email protected] — most fixes ship within 24 hours.