Turn any PDF into a flipbook with PdfSource from @zinejs/pdf.
Install
PDF support is a small add-on package. It depends on pdf.js ( pdfjs-dist).
pnpm add @zinejs/core @zinejs/pdfPdfSource
Pass a URL, raw bytes ( ArrayBuffer / Uint8Array), or a pre-created pdf.js document. Under most bundlers the worker is auto-resolved.
import { Zine } from '@zinejs/core'
import { PdfSource } from '@zinejs/pdf'
new Zine(document.getElementById('book'), {
source: new PdfSource('/catalog.pdf', { progressive: true }),
})Options
workerSrcoptional · default auto- URL to the pdf.js worker. Auto-resolved under bundlers; pass it for CDN, UMD, or custom paths.
renderScaledefault1- Base raster scale. Each page paints at
renderScale × devicePixelRatio. preloaddefault1- How many adjacent pages to prefetch around a requested page.
maxCacheBytesdefault ~256 MB- Soft cap on cached page bytes. Least-recently-used pages are evicted beyond this limit.
progressivedefaultfalse- Paint a low-res page first, then swap to crisp for a faster first paint.
disableAutoFetchdefaultfalse- Fetch only the byte ranges visible pages need. Requires a range-capable server.
legacydefaulttrue- Load pdf.js's transpiled legacy build (polyfills, broader reach) and the matching worker. Pass
falsefor the smaller modern build on recent engines only. Ignored when you pass a pre-created document or setglobalThis.pdfjsLib(CDN).
// Optional: pass workerSrc for CDN / UMD / custom paths
// Under Vite / webpack the worker is usually auto-resolved.
import pdfWorker from 'pdfjs-dist/legacy/build/pdf.worker.min.mjs?url'
new PdfSource('/catalog.pdf', {
workerSrc: pdfWorker,
renderScale: 1,
preload: 1,
progressive: true,
})Browser support
Image books need ordinary DOM, canvas, and fetch / createImageBitmap. PDF books go through pdf.js. The default legacy: true path is aimed at a wide range of engines. Mozilla documents the legacy build as Chrome 125+, Firefox ESR, Safari 18+, and Chromium Edge. In our tests, PDF text rasterizes correctly back to Chrome 114.
Where WebGL2 is unavailable, zinejs falls back to the CSS renderer on its own.
See the PDF example.