File & PDF Tools

Rotate PDF Pages

Rotate all or selected PDF pages clockwise.

Rotate PDF pages
Rotate every page or a selected page range.
Local browser processing

Rotate PDF Pages

Rotate every page or a selected range clockwise by 90, 180, or 270 degrees. Rotation is added to the existing orientation.

Use Cases

  • Correct scanned document orientation
  • Fix individual landscape tables or inserts
  • Page dimensions and content quality are preserved

Writes the /Rotate entry of a PDF page dictionary, turning selected pages clockwise by 90, 180 or 270 degrees. Content streams are never re-encoded, so scanned images and vector artwork keep their original resolution. Useful when a whole scan arrives sideways or a few inserted pages sit the wrong way up.

The file stores one integer, not rotated pixels

A PDF page dictionary carries a /Rotate entry defined in ISO 32000-1 Table 30: an integer number of degrees, clockwise when displayed or printed, which must be a multiple of 90 and defaults to 0. The attribute is inheritable through the page tree, and this tool writes an explicit value onto each selected page, overriding whatever a parent Pages node declared. Because that number sits beside /MediaBox instead of inside the content stream, a 90 degree turn leaves the box untouched: a US Letter page still measures 612 x 792 user units and is painted as 792 x 612. Text, images and vector paths are copied byte for byte, so nothing is resampled and no quality can be lost.

Why 270 plus 90 is saved as a plain zero

Processing reads the current angle, adds the chosen step, takes the remainder modulo 360 and writes the result back, so stacking is arithmetic rather than a counter. A page already at 270 degrees, rotated once more by 90, is saved with /Rotate 0: visually correct, but the file now looks as if it was never turned, and nothing in the output records that two operations happened. The JavaScript % operator keeps the sign of the dividend, so a source page carrying -90 survives a 90 degree step yet can end up negative after 270. Pages with angles that are not multiples of 90 also exist in malformed scans; pdf-lib then refuses the write and the panel shows degreesAngle must be a multiple of 90, but was actually 135 instead of a friendly explanation.

Range syntax, silent deduplication, untouched boxes

The page field is parsed token by token: every comma-separated part must be digits with an optional dash range, ranges may run backwards (5-3 means pages 5, 4 and 3), and one out-of-range number aborts the entire run rather than being skipped. Repeated pages are silently dropped, so typing 3,3 turns page 3 exactly once and does not add up to 180 degrees. Order carries no meaning here, unlike in the reorder tool, because the result is a set of page-dictionary writes. Cropping later uses the unrotated coordinate system: a top margin entered after a 90 degree turn still measures from the top of the pre-rotation page, not from the edge you see on screen.

Worked example

Stacking 90 degrees onto a page already at 270

Input
Two-page PDF: page 1 /Rotate 0, page 2 /Rotate 270; Pages field 1-2; rotation 90 degrees
Output
Page 1 /Rotate 90, page 2 /Rotate 0; both keep /MediaBox [0 0 612 792]

(0 + 90) % 360 = 90 and (270 + 90) % 360 = 0, so the second page is written as literal zero: a wrapped value, neither 360 nor a deleted entry. Only that integer changes — a one-page A4 test document went from 589 to 588 bytes — while the boxes stay put and viewers swap the displayed dimensions.

Limits and pitfalls

  • The selector offers only 90, 180 and 270 clockwise; counter-clockwise means picking 270, and there is no free-angle option because any other value would be illegal in /Rotate.
  • Each file must be 100 MB or smaller with a 250 MB total across the selection, and password-protected or encrypted PDFs are rejected while loading, before any page is written.
  • Rotation is applied per page, so pages left out of the range keep their original angle and the result can legitimately mix orientations that later print or imposition steps must handle.
  • Saving re-serializes the whole document, which invalidates existing digital signatures and byte-range linearization: the pages look identical but signature validation will report a broken file.

Related tools

When it goes wrong

I rotated the sideways scan first and stamped CONFIDENTIAL on it second, and now the watermark runs down the sheet instead of across it.

CauseWatermark and page-number modes paint into the page content stream, and pdf-lib lays that bitmap out in unrotated user space: drawImage never compensates for /Rotate, and getSize() returns the raw MediaBox (595 x 842 pt for A4) without swapping the sides. The mark is centred in the pre-rotation frame, then the viewer turns page content and the freshly drawn bitmap together, so it arrives at 90 degrees on a page carrying /Rotate 90.

FixSettle the orientation before stamping anything. If a mark has to read upright on pages that are already turned, flatten those pages first — render them through PDF to Images, rebuild them with Images to PDF, which yields pages at /Rotate 0 whose pixels are genuinely turned — and add the watermark to that rebuild.

The rotated copy landed in the shared folder and the sync client skipped it, because the modification date still reads last March.

CauseThe loader runs with updateMetadata: false, and the rotate branch reuses the document it parsed (output = source) instead of creating a new one, so pdf-lib never rewrites /Info: /ModDate and Producer keep the values the exporting application left. Only the page dictionaries differ, and nothing but the -rotate.pdf suffix marks the file as newer.

FixCompare by content hash rather than mtime, and name the output with a date if the folder sorts alphabetically. Where an archive needs a fresh timestamp, run the result through Edit PDF metadata once — that mode calls setModificationDate(new Date()).

A 60 MB scanned book locked the tab up, and it died on saving even though I had asked for four pages to be turned.

CauseThe turn itself writes one integer per selected page, but the document is edited in place and then serialised whole: readFileBytes hands pdf-lib a single Uint8Array of the entire file, parsing builds the object tree from those bytes, and output.save({ useObjectStreams: true }) serialises a second full copy before a Blob exists. Cost tracks file size, not how many pages were selected.

FixSplit the book into chapter-sized PDFs, rotate the parts and merge them back, so only one part is in memory at a time; the 100 MB read ceiling then applies per part rather than to the whole book.

The page is visibly lying on its side, the rotation property says 0, and my 90 degree pass left it upside down.

CausegetRotation() answers from the /Rotate key alone, walking up the page tree and defaulting to 0 when the key is absent; a quarter turn can also be painted by a cm matrix inside the content stream, which no page-dictionary read ever sees. The arithmetic (0 + 90) % 360 then starts from the wrong baseline and overshoots by half a turn.

FixRead the page rotation in a desktop reader before choosing a step: a sideways page whose property is 0 carries its direction in the content stream, so pick 270 for that page, not 90 — or rebuild it through PDF to Images so the matrix is replaced by pixels.

One concrete scenario

Twelve sideways plates inside a 240-page manual

A 240-page service manual came back from the scanner with its twelve fold-out plates, pages 88 through 99, lying on their side while the other 228 pages sit upright. Type 88-99 into Pages, leave the step at 90 degrees, press Rotate: the output keeps all 240 pages, twelve of them now carrying /Rotate 90 and 228 still at 0. An A4 sheet measures 595 x 842 pt, so those twelve display as 842 x 595 while their MediaBox never moves. Had the same plates arrived turned the other way, the step would be 270 instead. Rotating the whole document would leave 240 landscape pages and force a second pass to rescue the upright 228.

Frequently Asked Questions

Is rotation permanent? Does it cost quality?
Rotation is written into the page’s orientation attribute in the saved file — permanent — but it is a pure coordinate transform that never touches content data: zero quality change. If another viewer "shows it unrotated", distinguish the viewer’s view rotation from the file’s rotation.
Can I rotate only some pages?
Yes, by page range: all pages, single pages, or 1-3,5,8-10. Landscape tables inserted into portrait scans and mixed invoices are fastest handled by range.
What happens if I rotate an already-landscape page by 90°?
Rotation stacks on the existing orientation: a landscape page becomes a sideways-standing landscape page. For mis-scanned documents, rotate once, preview, and stack further 90/180/270 as needed.

Content reviewed: