Sometimes you only need one chapter of a report. Or you need to send the last 3 pages of a contract without the rest. Whatever the reason, splitting a PDF is a routine task, and it should be simple.
Here's how to do it, from the fastest browser method to full programmatic control.
Method 1: Browser tool (no upload, instant)
The most private approach: everything runs in your browser, files never leave your device.
Using PDF4.dev Split PDF:
- Go to Split PDF
- Drop your PDF onto the upload area
- Enter a page range, for example
1-3to extract pages 1 through 3, or2,5,7for specific pages - Click "Split PDF"
- Download the result
Splitting every page into a separate file:
Toggle "Split all pages" to extract each page as its own PDF. You'll get a zip archive with one file per page.
Method 2: macOS Preview
Preview can extract pages without any extra software.
- Open your PDF in Preview
- Show the sidebar: View → Thumbnails
- Select the pages you want (hold
Cmdfor multiple,Shiftfor a range) - Drag the selected thumbnails to your Desktop or a Finder window, this exports those pages as a new PDF
To delete specific pages instead (the reverse):
- Select the pages to remove
- Press
Delete - Save with File → Export as PDF
Method 3: Command line
Using pdftk (page range)
# Extract pages 3 to 7
pdftk input.pdf cat 3-7 output extracted.pdf
# Extract specific pages: 1, 5, 8
pdftk input.pdf cat 1 5 8 output extracted.pdf
# Split every page into its own file
pdftk input.pdf burst output page_%02d.pdfUsing qpdf
# Extract pages 3 to 7
qpdf input.pdf --pages . 3-7 -- output.pdf
# Every page to a separate file
for i in $(seq 1 $(qpdf --show-npages input.pdf)); do
qpdf input.pdf --pages . $i -- page_$i.pdf
doneUsing Ghostscript
# Extract pages 2 through 5
gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite \
-dFirstPage=2 -dLastPage=5 \
-sOutputFile=extracted.pdf input.pdfMethod 4: JavaScript with pdf-lib
For Node.js applications:
import { PDFDocument } from 'pdf-lib';
import fs from 'fs';
async function extractPages(inputPath, pages, outputPath) {
const bytes = fs.readFileSync(inputPath);
const original = await PDFDocument.load(bytes);
const extracted = await PDFDocument.create();
// pages is a 0-indexed array, e.g. [0, 2, 4] for pages 1, 3, 5
const copied = await extracted.copyPages(original, pages);
copied.forEach(page => extracted.addPage(page));
const output = await extracted.save();
fs.writeFileSync(outputPath, output);
console.log(`Extracted ${pages.length} pages to ${outputPath}`);
}
// Extract pages 1–3 (0-indexed: 0, 1, 2)
await extractPages('report.pdf', [0, 1, 2], 'intro.pdf');Splitting every page:
async function splitAllPages(inputPath) {
const bytes = fs.readFileSync(inputPath);
const original = await PDFDocument.load(bytes);
const count = original.getPageCount();
for (let i = 0; i < count; i++) {
const single = await PDFDocument.create();
const [page] = await single.copyPages(original, [i]);
single.addPage(page);
const output = await single.save();
fs.writeFileSync(`page_${i + 1}.pdf`, output);
}
console.log(`Split into ${count} files`);
}Method 5: Python with pypdf
from pypdf import PdfWriter, PdfReader
def extract_pages(input_path, page_range, output_path):
reader = PdfReader(input_path)
writer = PdfWriter()
for page_num in page_range:
writer.add_page(reader.pages[page_num])
with open(output_path, "wb") as f:
writer.write(f)
# Extract pages 1-3 (0-indexed)
extract_pages("report.pdf", range(0, 3), "intro.pdf")
# Split every page
def split_all_pages(input_path):
reader = PdfReader(input_path)
for i, page in enumerate(reader.pages):
writer = PdfWriter()
writer.add_page(page)
with open(f"page_{i+1}.pdf", "wb") as f:
writer.write(f)Comparing Methods
| Method | Setup | Batch | Privacy | Speed |
|---|---|---|---|---|
| Browser tool | None | Manual | 100% local | Instant |
| macOS Preview | None | Manual | Local | Fast |
| pdftk / qpdf | Install | Scriptable | Local | Fast |
| pdf-lib (Node.js) | npm install pdf-lib | Yes | Local | Fast |
| pypdf (Python) | pip install pypdf | Yes | Local | Fast |
Common use cases
Extracting an invoice from a statement
Bank statements often come as multi-page PDFs. Extract the single page you need to attach to an expense report:
pdftk statement.pdf cat 3 output invoice_march.pdfSplitting a book into chapters
If you know the page ranges for each chapter, script it:
pdftk book.pdf cat 1-12 output ch1.pdf
pdftk book.pdf cat 13-28 output ch2.pdf
pdftk book.pdf cat 29-45 output ch3.pdfRemoving a cover page before sharing
Sometimes you want to strip the first page (a confidential cover sheet, or a page with personal info):
# Remove first page: start from page 2
pdftk document.pdf cat 2-end output without-cover.pdfSplitting in a programmatic workflow
The methods above all operate on existing PDFs. If you're building an application that generates PDFs, there's often a smarter approach: instead of generating a large document and splitting it, generate targeted PDFs from the start.
Say you're generating monthly statements: 12 pages in one PDF, and your customers only need their own page. Instead of splitting a merged document, generate each statement individually:
async function generateStatement(customerId, month, data) {
const response = await fetch('https://pdf4.dev/api/v1/render', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PDF4_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
template_id: 'monthly-statement',
data: { ...data, customer_id: customerId, month },
}),
});
return Buffer.from(await response.arrayBuffer());
}
// Generate 100 individual statements without any splitting step
for (const customer of customers) {
const pdf = await generateStatement(customer.id, 'March 2026', customer.data);
await saveToStorage(pdf, `statement-${customer.id}-march.pdf`);
}No merging, no splitting, no intermediate files. Each PDF is generated with exactly the content it needs. This is the approach that scales.
PDF4.dev has a free tier. Create a template and start generating targeted PDFs without post-processing.
FAQ
Will splitting reduce quality?
No. Pages are copied as-is using pdf-lib's copyPages() method, with no re-encoding or re-compression. All embedded fonts, images, and annotations are preserved at original quality. The output structure differs slightly (new cross-reference table, new file header) but the page content is functionally identical to the original.
Can I split password-protected PDFs?
You need to unlock the PDF first. Once unlocked, you can split normally.
What's the difference between "split" and "extract"?
They're the same operation. "Split" often implies separating into multiple files (e.g. one file per page), while "extract" implies pulling a specific range into a new file. Most tools support both.
Does splitting break internal links or bookmarks?
Internal links that point to pages no longer included in the extracted range will break. Bookmarks may also be lost depending on the tool. If you need to preserve these, use a dedicated tool like pdftk's burst mode followed by manual bookmark management.
Can I split and then re-merge in a different order?
Yes, this is the standard workflow for reordering pages. Split → reorder externally → merge. Or use a reorder tool that handles it in one step.
Free tools mentioned:
Start generating PDFs
Build PDF templates with a visual editor. Render them via API from any language in ~300ms.