npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zinejs/pdf

v0.8.2

Published

PDF content source for zinejs, powered by pdf.js.

Downloads

1,680

Readme

@zinejs/pdf

PDF content source for zinejs, powered by pdf.js. Renders PDF pages to canvases that the zinejs core paints as a flipbook.

Install

npm install @zinejs/core @zinejs/pdf

pdfjs-dist is a normal dependency of @zinejs/pdf, so it installs with the package. The plugin still loads it lazily (dynamic import) so it never lands in the @zinejs/core bundle. If your app already depends on pdfjs-dist, the package manager will typically dedupe to one copy — keep major versions compatible so the worker matches the library.

Usage

import { Zine } from '@zinejs/core';
import { PdfSource } from '@zinejs/pdf';

const book = new Zine(document.getElementById('book'), {
  source: new PdfSource('document.pdf'),
});

Under a bundler that's all you need — the pdf.js worker is resolved for you.

CDN / no bundler

Both packages ship UMD builds (dist/index.umd.js) that share the ZineJS global — load core first, then pdf (the pdf build uses extend: true so it merges into ZineJS instead of replacing it).

Modern pdfjs-dist is ESM-only, so load it in a module script first, expose globalThis.pdfjsLib, then use classic deferred <script> tags for the UMD builds (and pass an explicit workerSrc — no bundler rewrites the worker URL):

<script type="module">
  import * as pdfjsLib from 'https://cdn.jsdelivr.net/npm/pdfjs-dist/build/pdf.min.mjs';
  globalThis.pdfjsLib = pdfjsLib;
</script>

<script defer src="https://cdn.jsdelivr.net/npm/@zinejs/core/dist/index.umd.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/@zinejs/pdf/dist/index.umd.js"></script>
<script defer>
  const book = new ZineJS.Zine(document.getElementById('book'), {
    source: new ZineJS.PdfSource('document.pdf', {
      workerSrc: 'https://cdn.jsdelivr.net/npm/pdfjs-dist/build/pdf.worker.min.mjs',
    }),
  });
</script>

Image-only books can skip pdf.js and use a plain classic script:

<script src="https://cdn.jsdelivr.net/npm/@zinejs/core/dist/index.umd.js"></script>
<script>
  new ZineJS.Zine(document.getElementById('book'), {
    source: new ZineJS.ImageSource(['page-01.png', 'page-02.png']),
  });
</script>

PdfSource prefers globalThis.pdfjsLib when present (CDN), otherwise dynamic-imports pdfjs-dist (bundlers).

The pdf.js worker (workerSrc)

pdf.js parses and rasterizes in a Web Worker, a separate file the host must locate. By default PdfSource resolves it to (the legacy/ path since legacy defaults to true; build/ when legacy: false):

new URL('pdfjs-dist/legacy/build/pdf.worker.min.mjs', import.meta.url).href

Resolution precedence: an explicit workerSrc option → an already-set pdfjsLib.GlobalWorkerOptions.workerSrc → the auto-default above. You only pass workerSrc when the default can't apply.

Vite / webpack 5 / esbuild

Nothing to do — these bundlers statically rewrite the new URL(..., import.meta.url) above and emit the worker asset:

new PdfSource('document.pdf');

Custom path

Serving the worker yourself (copied to your public dir, etc.):

new PdfSource('document.pdf', { workerSrc: '/assets/pdf.worker.min.mjs' });

Already configuring pdf.js yourself

If your app sets GlobalWorkerOptions.workerSrc, PdfSource leaves it alone — no workerSrc needed.

Passing bytes or a pre-created document

new PdfSource(arrayBuffer);              // raw PDF bytes (ArrayBuffer | Uint8Array)
new PdfSource(await getDocument(...).promise); // a pdf.js document you created; no workerSrc needed

Options

new PdfSource(src, {
  workerSrc,          // string — override the auto-resolved worker URL (see above)
  renderScale: 1,      // pages rasterize at renderScale × devicePixelRatio
  preload: 1,          // adjacent pages to prefetch around a requested page
  maxCacheBytes,       // soft cap on cached page bytes (default ~256 MB); LRU-evicts beyond it
  progressive: true,   // paint a low-res page first, then swap to crisp (faster first paint)
  disableAutoFetch: true, // fetch only the byte ranges visible pages need (range-capable servers)
  legacy: true,        // load pdf.js's transpiled build (default); false serves the lean modern build
});

src is a URL string, ArrayBuffer/Uint8Array of PDF bytes, or a pre-created pdf.js document.

Legacy vs modern build (legacy)

pdf.js ships two builds. The legacy build is transpiled with polyfills and runs on both older and current browsers; the modern build is smaller and a touch faster but needs a recent engine. PdfSource defaults to legacy: true, favouring reach. Pass legacy: false to load the modern build when your audience is on current browsers:

new PdfSource('document.pdf', { legacy: false });

The flag also picks the matching worker (legacy/build/pdf.worker.min.mjs vs build/pdf.worker.min.mjs) — the two must be a matched pair. It's ignored when you pass a pre-created document or set globalThis.pdfjsLib, since those already chose their build.