Get started

How to reorder PDF pages (free online and programmatic methods)

Rearrange PDF pages in any order, free and in your browser, or automate page reordering with JavaScript, Python, and pdf-lib. No upload needed.

benoitdedMarch 26, 202611 min read

Reordering PDF pages means changing the sequence of pages in a document without altering the content. It is a common task when assembling reports, correcting scanned documents, or reorganizing slide decks. This guide covers the free browser-based method, programmatic approaches in JavaScript and Python, and how to handle edge cases like links and bookmarks.

How to reorder PDF pages online (free, no upload)

The fastest way to rearrange PDF pages is PDF4.dev's free Reorder PDF tool. Open the tool, drop your PDF, drag the page thumbnails into the order you want, and download the result. The whole process runs in your browser using pdf-lib — your file never reaches a server.

Steps:

  1. Open pdf4.dev/tools/reorder-pdf
  2. Drop your PDF onto the upload area or click to browse
  3. Drag the page thumbnails into the new order
  4. Click Download reordered PDF

No account is required. The tool handles multi-page PDFs up to several hundred pages. For large files, loading thumbnails may take a few seconds as the browser renders each page from the PDF's vector data.

Reorder PDF pages with JavaScript (pdf-lib)

pdf-lib is a pure JavaScript library for creating and modifying PDFs in Node.js and browsers. It does not shell out to Chromium or require a server — all processing happens in memory.

To reorder pages, copy all pages from the source document, create a new document, and add pages in the desired sequence:

import { PDFDocument } from "pdf-lib";
import { readFileSync, writeFileSync } from "fs";
 
async function reorderPages(
  inputPath: string,
  newOrder: number[], // 0-based page indices in desired order
  outputPath: string
): Promise<void> {
  const pdfBytes = readFileSync(inputPath);
  const srcDoc = await PDFDocument.load(pdfBytes);
  const dstDoc = await PDFDocument.create();
 
  const copiedPages = await dstDoc.copyPages(srcDoc, newOrder);
  for (const page of copiedPages) {
    dstDoc.addPage(page);
  }
 
  const newPdfBytes = await dstDoc.save();
  writeFileSync(outputPath, newPdfBytes);
}
 
// Move page 3 to the front: [2, 0, 1, 3, 4, ...]
await reorderPages("input.pdf", [2, 0, 1, 3, 4], "output.pdf");

The copyPages method accepts an array of 0-based page indices in any order. Passing [2, 0, 1] copies page 3 first, then page 1, then page 2. Repeated indices are allowed, which means you can duplicate pages in the same call.

Generating the newOrder array programmatically

For systematic reordering, calculate the index array rather than hardcoding it:

import { PDFDocument } from "pdf-lib";
import { readFileSync, writeFileSync } from "fs";
 
async function reversePages(inputPath: string, outputPath: string) {
  const pdfBytes = readFileSync(inputPath);
  const srcDoc = await PDFDocument.load(pdfBytes);
  const pageCount = srcDoc.getPageCount();
 
  // Reverse order: [n-1, n-2, ..., 1, 0]
  const reversedOrder = Array.from({ length: pageCount }, (_, i) => pageCount - 1 - i);
 
  const dstDoc = await PDFDocument.create();
  const pages = await dstDoc.copyPages(srcDoc, reversedOrder);
  for (const page of pages) dstDoc.addPage(page);
 
  writeFileSync(outputPath, await dstDoc.save());
}
 
// Move one page: swap pages at index a and b
function swapPages(order: number[], a: number, b: number): number[] {
  const newOrder = [...order];
  [newOrder[a], newOrder[b]] = [newOrder[b], newOrder[a]];
  return newOrder;
}

Reorder PDF pages with Python (PyPDF)

PyPDF (formerly PyPDF2) is the standard Python library for PDF manipulation. It handles page reordering with a reader/writer pattern:

from pypdf import PdfReader, PdfWriter
 
def reorder_pages(input_path: str, new_order: list[int], output_path: str) -> None:
    """
    new_order: list of 0-based page indices in desired sequence.
    Example: [2, 0, 1] moves page 3 to the front.
    """
    reader = PdfReader(input_path)
    writer = PdfWriter()
 
    for page_index in new_order:
        writer.add_page(reader.pages[page_index])
 
    with open(output_path, "wb") as f:
        writer.write(f)
 
# Reverse all pages
page_count = PdfReader("input.pdf").get_num_pages()
reorder_pages("input.pdf", list(range(page_count - 1, -1, -1)), "reversed.pdf")

PyMuPDF (fitz) offers the most concise API: doc.select(indices) reorders, duplicates, or removes pages in one call. It is also the fastest Python PDF library for most operations, running roughly 5-10x faster than pypdf on large documents.

Comparison: Python PDF libraries for page reordering

LibraryInstallAPI styleSpeed (100 pages)Handles encrypted PDFs
PyPDFpip install pypdfreader/writer~200msYes (with password)
PyMuPDFpip install pymupdfdocument.select()~30msYes (with password)
pdfminer.sixpip install pdfminer.sixlow-levelNot designed for manipulationNo

For page reordering, PyMuPDF is the fastest option. PyPDF is a lighter dependency if PyMuPDF's binary size is a concern.

Reorder PDF pages in a web app (React + pdf-lib)

For a drag-and-drop reorder UI, combine pdfjs-dist for thumbnail rendering with pdf-lib for the actual reordering:

import { useState, useEffect } from "react";
import { PDFDocument } from "pdf-lib";
import * as pdfjs from "pdfjs-dist";
 
pdfjs.GlobalWorkerOptions.workerSrc = "/pdf.worker.min.js";
 
interface PageThumb {
  index: number;
  dataUrl: string;
}
 
export function PdfReorder({ file }: { file: File }) {
  const [thumbs, setThumbs] = useState<PageThumb[]>([]);
  const [order, setOrder] = useState<number[]>([]);
 
  useEffect(() => {
    (async () => {
      const buffer = await file.arrayBuffer();
      const pdf = await pdfjs.getDocument({ data: buffer }).promise;
      const pages: PageThumb[] = [];
 
      for (let i = 1; i <= pdf.numPages; i++) {
        const page = await pdf.getPage(i);
        const viewport = page.getViewport({ scale: 0.3 });
        const canvas = document.createElement("canvas");
        canvas.width = viewport.width;
        canvas.height = viewport.height;
        await page.render({ canvasContext: canvas.getContext("2d")!, viewport }).promise;
        pages.push({ index: i - 1, dataUrl: canvas.toDataURL() });
      }
 
      setThumbs(pages);
      setOrder(pages.map((p) => p.index));
    })();
  }, [file]);
 
  async function handleDownload() {
    const pdfBytes = await file.arrayBuffer();
    const srcDoc = await PDFDocument.load(pdfBytes);
    const dstDoc = await PDFDocument.create();
    const copied = await dstDoc.copyPages(srcDoc, order);
    for (const page of copied) dstDoc.addPage(page);
    const blob = new Blob([await dstDoc.save()], { type: "application/pdf" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = "reordered.pdf";
    a.click();
  }
 
  // Swap positions on drag-and-drop (simplified)
  function moveThumb(fromIndex: number, toIndex: number) {
    const newOrder = [...order];
    const [moved] = newOrder.splice(fromIndex, 1);
    newOrder.splice(toIndex, 0, moved);
    setOrder(newOrder);
  }
 
  return (
    <div>
      <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
        {order.map((pageIndex, position) => (
          <img
            key={pageIndex}
            src={thumbs[pageIndex]?.dataUrl}
            alt={`Page ${pageIndex + 1}`}
            draggable
            onDragOver={(e) => e.preventDefault()}
            onDrop={() => moveThumb(thumbs.findIndex((t) => t.dataUrl === thumbs[pageIndex].dataUrl), position)}
            style={{ width: 80, cursor: "grab", border: "1px solid #ccc" }}
          />
        ))}
      </div>
      <button onClick={handleDownload}>Download reordered PDF</button>
    </div>
  );
}

This pattern (pdfjs for thumbnails + pdf-lib for manipulation) is exactly how PDF4.dev's Reorder PDF tool works. The key insight: pdfjs renders pages to canvas for preview, while pdf-lib handles the actual file modification — the two libraries complement each other.

How page reordering works inside a PDF

A PDF file stores pages as independent objects with their own resource dictionaries. The document's page tree (a /Pages node in the PDF cross-reference table) lists pages in display order. Reordering updates the page tree references, not the page content objects themselves.

This is why reordering is fast and lossless. The content streams (text, images, vector graphics) are not touched — only the order in which they appear in the page tree changes. A typical 10-page reorder operation produces a file nearly identical in size to the original.

One side effect: the original page objects may remain in the PDF's cross-reference table even if they're no longer referenced (orphaned objects). Running the output through a PDF linearizer or compressor removes these. PDF4.dev's Compress PDF tool can clean up orphaned objects as part of compression.

Edge cases and gotchas

PDFs store internal links as /GoTo actions that reference a page by its page object number or by index. After reordering, a link that previously pointed to "page 3" may now point to the wrong page.

To audit internal links after reordering, open the PDF in a reader and test every bookmark or cross-reference. If you control the source HTML for programmatic PDF generation (via PDF4.dev's API), the cleaner approach is to generate the PDF with links intact after establishing the final page order.

Bookmarks (outlines)

PDF bookmarks (the outline panel in PDF viewers) reference specific pages. After reordering, bookmarks may point to incorrect pages. PyMuPDF provides doc.get_toc() and doc.set_toc() for reading and rewriting the table of contents after reordering, which lets you remap bookmarks to their new positions.

Encrypted and permission-restricted PDFs

PDFs can have two types of passwords: a user password (required to open the file) and an owner password (required to edit it). Reordering pages is an editing operation. If the PDF's permissions restrict page manipulation, you need the owner password to proceed.

Remove restrictions first using PDF4.dev's free tools, then reorder pages. See our guide on how to remove a password from a PDF for the full workflow.

Very large PDFs (500+ pages)

Browser-based reordering loads all pages into memory for thumbnail rendering. For PDFs over 300-400 pages, a Node.js or Python script is more reliable. Both pdf-lib and PyMuPDF handle large files by streaming page data rather than loading all content at once:

import fitz
 
# fitz.open() is lazy — pages are loaded on access, not all at once
doc = fitz.open("large-document.pdf")
 
# select() builds the new page list without rendering thumbnails
new_order = list(range(doc.page_count - 1, -1, -1))  # reverse
doc.select(new_order)
doc.save("output.pdf", garbage=3, deflate=True)  # garbage=3 removes orphaned objects

The garbage=3 option in PyMuPDF removes unreferenced objects from the output file, equivalent to running a PDF linearizer pass. This is useful after any restructuring operation.

Comparison: tools and methods for reordering PDF pages

MethodBest forEffortFile privacyCost
PDF4.dev Reorder PDFQuick one-off, any fileNoneFile stays in browserFree
Adobe AcrobatProfessional workflowsMediumCloud or localPaid
pdf-lib (JavaScript)Web apps, automationLow codeYour infrastructureFree (library)
PyMuPDF (Python)Batch processing, large PDFsLow codeYour infrastructureFree (library)
PyPDF (Python)Simple scriptsLow codeYour infrastructureFree (library)

For most users, the Reorder PDF tool is the fastest path. For batch reordering (hundreds of PDFs) or integration into an existing workflow, PyMuPDF's doc.select() is the most concise programmatic option.

Combine reorder with split and merge for complex workflows

Reordering is often one step in a larger document assembly workflow. Common patterns:

Assemble a report from multiple sources:

  1. Split each source PDF into individual pages
  2. Collect the pages you need in the desired order
  3. Merge them into the final document

Correct a scanned document:

  1. Open the scanned PDF in the Reorder PDF tool
  2. Drag pages into the correct sequence
  3. Download the corrected document

Remove specific pages then reorder the remainder:

  1. Use Delete Pages to remove unwanted pages
  2. Reorder the remaining pages in the Reorder PDF tool

For programmatic workflows combining these operations, see our guides on how to split a PDF into individual pages and how to merge PDF files.

Summary

Reordering PDF pages is a lossless operation that changes page sequence without altering content quality. Use PDF4.dev's free Reorder PDF tool for quick visual reordering in your browser. For programmatic use:

  • JavaScript: pdf-lib with copyPages() and addPage() in any order
  • Python: PyMuPDF's doc.select(indices) is the fastest single-call API; PyPDF's reader/writer pattern is the standard alternative

Watch for internal links and bookmarks after reordering — they reference pages by index and may need to be remapped. For large files over a few hundred pages, prefer a server-side script over browser-based tools.

Free tools mentioned:

Reorder PdfTry it freeMerge PdfTry it freeSplit PdfTry it freeDelete PagesTry it free

Start generating PDFs

Build PDF templates with a visual editor. Render them via API from any language in ~300ms.