Rotating PDF pages is one of the most common quick-fix tasks: a scanned document came in sideways, a shared file has a landscape page in a portrait report, or a photo was taken in the wrong orientation. The fix takes under 30 seconds with the right tool.
This guide covers every method: browser tool, macOS Preview, command line, and code, so you can pick what fits your workflow.
Method 1: Browser-based tool (fastest, recommended)
The fastest way to rotate PDF pages is PDF4.dev's free browser tool. No software, no account, no upload to any server.
- Go to Rotate PDF
- Upload your file (drag and drop or click to browse)
- Select the pages you want to rotate by clicking their thumbnails
- Choose the rotation angle: 90°, 180°, or 270° clockwise
- Click Rotate PDF and download
Why it works well:
- Rotation is saved permanently into the file, not just the viewer
- Works on any page subset, you can rotate page 3 and leave everything else untouched
- Files are processed by
pdf-libin your browser, they never reach a server - No file size limits, no watermarks
Method 2: macOS Preview
If you're on a Mac, Preview can rotate pages without any extra tools.
- Open the PDF in Preview
- Go to View > Thumbnails to show the sidebar
- Click the page thumbnail you want to rotate
- Use Tools > Rotate Left (
⌘L) or Tools > Rotate Right (⌘R) - Go to File > Export as PDF to save the rotated version
Important: use "Export as PDF", not "Save". The standard Save action does not always write rotation changes permanently. Exporting creates a clean new file with the rotation baked in.
Limitations:
- macOS only
- Must export (not just save) to make rotation permanent
- Batch rotating many pages is tedious via the UI
Method 3: Command line
For scripting or batch processing, command-line tools give you precise control.
Using qpdf
qpdf is the most reliable free CLI tool for PDF rotation. Install with brew install qpdf on macOS or apt install qpdf on Linux.
# Rotate all pages 90 degrees clockwise
qpdf --rotate=+90 input.pdf output.pdf
# Rotate all pages 90 degrees counter-clockwise
qpdf --rotate=-90 input.pdf output.pdf
# Rotate page 3 only, 180 degrees
qpdf --rotate=180:3 input.pdf output.pdf
# Rotate pages 1-3 clockwise, page 5 counter-clockwise
qpdf --rotate=+90:1-3 --rotate=-90:5 input.pdf output.pdfThe + prefix means clockwise, - means counter-clockwise. Page ranges use 1-3, 2,4,6 or z for the last page.
Using Ghostscript
Ghostscript can also rotate pages, though the syntax is less ergonomic:
# Rotate all pages 90 degrees clockwise
gs -dBATCH -dNOPAUSE -dQUIET \
-sDEVICE=pdfwrite \
-dAutoRotatePages=/None \
-c "<</Orientation 3>> setpagedevice" \
-f input.pdf \
-sOutputFile=output.pdfOrientation values: 0 = portrait, 1 = landscape (90° CCW), 2 = portrait (180°), 3 = landscape (270° CCW).
Recommendation: prefer qpdf for rotation. Ghostscript is better suited for compression and format conversion.
Method 4: Code
For developers who need to rotate PDFs as part of an automated pipeline.
Node.js with pdf-lib
import { PDFDocument, degrees } from 'pdf-lib';
import fs from 'fs';
async function rotatePdfPages(inputPath, outputPath, pageIndexes, angle) {
const pdfBytes = fs.readFileSync(inputPath);
const pdf = await PDFDocument.load(pdfBytes);
for (const index of pageIndexes) {
const page = pdf.getPage(index);
const currentRotation = page.getRotation().angle;
page.setRotation(degrees(currentRotation + angle));
}
const rotatedBytes = await pdf.save();
fs.writeFileSync(outputPath, rotatedBytes);
}
// Rotate pages 0 and 2 (zero-indexed) by 90 degrees clockwise
rotatePdfPages('document.pdf', 'rotated.pdf', [0, 2], 90);pdf-lib uses zero-indexed pages (page 1 in the viewer = index 0 in code). The setRotation method takes a degrees() value, which is added to the existing rotation, so calling it twice accumulates.
Python with pypdf
from pypdf import PdfReader, PdfWriter
def rotate_pdf_pages(input_path, output_path, page_numbers, angle):
reader = PdfReader(input_path)
writer = PdfWriter()
for i, page in enumerate(reader.pages):
if i in page_numbers:
page.rotate(angle)
writer.add_page(page)
with open(output_path, 'wb') as f:
writer.write(f)
# Rotate pages 0 and 2 (zero-indexed) by 90 degrees
rotate_pdf_pages('document.pdf', 'rotated.pdf', {0, 2}, 90)pypdf is the actively maintained fork of PyPDF2. Install with pip install pypdf. The rotate() method takes an angle in degrees and rotates clockwise.
Rotating all pages in a directory (batch)
from pypdf import PdfReader, PdfWriter
import os
def batch_rotate(input_dir, output_dir, angle=90):
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if not filename.endswith('.pdf'):
continue
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
reader = PdfReader(input_path)
writer = PdfWriter()
for page in reader.pages:
page.rotate(angle)
writer.add_page(page)
with open(output_path, 'wb') as f:
writer.write(f)
print(f'Rotated: {filename}')
batch_rotate('scanned_docs/', 'corrected_docs/', angle=90)This is useful for bulk-correcting scanner output where all pages come out in the wrong orientation.
Comparing methods
| Method | Setup | Best for | Permanent | Batch |
|---|---|---|---|---|
| PDF4.dev browser tool | None | Quick fixes, any device | Yes | Manual |
| macOS Preview | macOS only | One-off edits on Mac | Yes (export) | No |
| qpdf (CLI) | Install qpdf | Scripting, automation | Yes | Yes |
| Ghostscript (CLI) | Install GS | Complex pipelines | Yes | Yes |
| pdf-lib (Node.js) | npm install | Apps, APIs | Yes | Yes |
| pypdf (Python) | pip install | Scripts, automation | Yes | Yes |
Why "rotate in viewer" does not stick
PDF viewers like Chrome, Firefox, and some versions of Preview can rotate a page in the display without changing the file. When you share or reopen that PDF, the original orientation comes back.
This is because the PDF format stores rotation as a metadata flag (/Rotate in the page dictionary). Viewer rotation only changes what the application renders on screen, it does not write the flag back to the file on disk.
To rotate permanently, you need a tool that writes the /Rotate value into the PDF file structure. All methods in this article do that.
Rotate as part of a PDF generation workflow
If you're generating PDFs programmatically (invoices, reports, certificates) and the output comes out in the wrong orientation, fixing it with post-processing rotation is the wrong layer. The better fix is to set the correct page format at generation time.
With the PDF4.dev API, page orientation is controlled via the format parameter:
curl -X POST https://pdf4.dev/api/v1/render \
-H "Authorization: Bearer p4_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"template_id": "my-report",
"data": { "title": "Q1 Report" },
"format": {
"preset": "a4-landscape"
}
}'Available presets: a4, a4-landscape, letter, letter-landscape, square, custom. Setting the correct preset at generation time means no rotation step is ever needed downstream.
For custom dimensions:
"format": {
"preset": "custom",
"width": "297mm",
"height": "210mm"
}Need to generate PDFs programmatically with correct orientation from the start? PDF4.dev offers a free tier with a visual template editor and REST API. Get started free.
Related tools
If you need to do more with your PDF after rotating:
- Merge PDFs — combine multiple files into one
- Split PDF — extract specific pages
- Reorder pages — drag pages into a new order
- Compress PDF — reduce file size after editing
Free tools mentioned:
Start generating PDFs
Build PDF templates with a visual editor. Render them via API from any language in ~300ms.