PDF.js Library (Legacy `pdfjs-lib` package)
PDF.js is a Portable Document Format (PDF) library built with HTML5, aiming to create a general-purpose, web standards-based platform for parsing and rendering PDFs. The package `pdfjs-lib` with version `0.0.149` (as provided) refers to a very old and effectively abandoned build of the PDF.js library. Its last known publish was over three years ago. The actively maintained and widely used package for consuming Mozilla's PDF.js library is `pdfjs-dist`. The current stable version of `pdfjs-dist` is around `5.6.205`, with a healthy and positive release cadence, often seeing multiple new versions within a few months, and continuous community interaction. Key differentiators include its robust HTML5-based rendering capabilities, cross-browser compatibility, and its role as the underlying technology for Firefox's built-in PDF viewer. It supports rendering PDFs onto HTML5 `<canvas>` elements, including a selectable text layer for search and copy-paste. While `pdfjs-lib` (0.0.149) may still exist on npm, it should be considered deprecated and developers are strongly advised to use `pdfjs-dist` for any new or existing projects.
Common errors
-
Failed to load worker script at file://.../pdf.worker.js (or similar URL) (reason: cross-origin or MIME type error)
cause The `pdfjsLib.GlobalWorkerOptions.workerSrc` path is incorrect, inaccessible, or served with the wrong MIME type. This is a common issue with local development or incorrect bundling configurations.fixVerify the `workerSrc` URL. It must be an accessible HTTP(S) URL or a data URL, not a `file://` URL for browser contexts. Ensure your web server or CDN serves `pdf.worker.min.mjs` with the correct `application/javascript` MIME type. Using a CDN for `workerSrc` is often the easiest solution (e.g., `//cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`). -
Uncaught SyntaxError: Cannot use import statement outside a module
cause Attempting to use ES module `import` syntax in a CommonJS (`require`) environment, or in a script tag without `type="module"`. This happens frequently when migrating older projects or misconfiguring bundlers.fixEnsure your project is configured for ES modules (e.g., `"type": "module"` in `package.json`, using `.mjs` file extensions, or a bundler like Webpack/Rollup). If using Node.js, dynamically import `pdfjs-dist` using `await import('pdfjs-dist')`. For browser scripts, add `type="module"` to your script tag. -
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
cause This error, common in React/Next.js applications, often indicates an incorrect default vs. named import, or a misconfiguration of `pdfjs-dist` that results in an `undefined` or malformed object being imported.fixEnsure you are using `import * as pdfjsLib from 'pdfjs-dist/build/pdf';` for the main library and correctly setting `GlobalWorkerOptions.workerSrc`. For Next.js, ensure dynamic imports are used where appropriate and refer to specific Next.js integration guides for `pdfjs-dist`. -
Error: Missing `standardFontDataUrl` parameter.
cause When running `pdfjs-dist` in Node.js environments and dealing with PDFs that require standard fonts, the library needs to know where to find the font data.fixProvide the `standardFontDataUrl` option to `pdfjsLib.getDocument()` or configure it globally. This usually points to the `standard_fonts` directory within `pdfjs-dist`. Example: `standardFontDataUrl: path.join(__dirname, 'node_modules/pdfjs-dist/standard_fonts/')`.
Warnings
- breaking The `pdfjs-lib` package (version `0.0.149`) is extremely outdated and effectively abandoned. It is not maintained by the Mozilla PDF.js team and lacks modern features, performance improvements, and security updates found in `pdfjs-dist`. Projects currently using `pdfjs-lib` should migrate to `pdfjs-dist`.
- gotcha The PDF.js library relies heavily on Web Workers for parsing and rendering to prevent UI freezes. The `pdfjsLib.GlobalWorkerOptions.workerSrc` property **must** be set to the correct URL of the `pdf.worker.mjs` (or `pdf.worker.js` for older builds/legacy) file. Incorrectly setting this path is a very common source of errors.
- gotcha Modern versions of `pdfjs-dist` (typically from v2.x onwards) are built as ES Modules (`.mjs`). Directly `require()`-ing them in a CommonJS-only environment without proper transpilation or dynamic imports will lead to errors like 'Cannot use import statement outside a module'.
- gotcha For compatibility with older browsers or environments that lack support for modern JavaScript features (e.g., optional chaining, nullish coalescing, private class fields), `pdfjs-dist` provides a `legacy/` folder containing ES5-compatible builds.
- gotcha Rendering large or complex PDF documents can consume significant memory and CPU, potentially leading to performance bottlenecks or crashes, especially on less powerful devices or in environments without Web Workers.
Install
-
npm install pdfjs-lib -
yarn add pdfjs-lib -
pnpm add pdfjs-lib
Imports
- getDocument
const pdfjsLib = require('pdfjs-dist'); // `pdfjs-dist/build/pdf` is the entry point, not root const { getDocument } = pdfjsLib;import { getDocument } from 'pdfjs-dist/build/pdf'; - GlobalWorkerOptions
import { GlobalWorkerOptions } from 'pdfjs-dist/build/pdf'; // GlobalWorkerOptions is on the main export object pdfjsLib.GlobalWorkerOptions.workerSrc = './pdf.worker.js'; // Incorrect worker path, must be correct URLimport * as pdfjsLib from 'pdfjs-dist/build/pdf'; pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`; - pdf.worker.mjs
const worker = require('pdfjs-dist/build/pdf.worker'); // Old CommonJS worker import pdfjsLib.GlobalWorkerOptions.workerSrc = worker; // May not resolve to correct URLimport pdfjsWorker from 'pdfjs-dist/build/pdf.worker.mjs'; pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
Quickstart
import * as pdfjsLib from 'pdfjs-dist/build/pdf';
// Set the workerSrc to enable PDF.js to load the worker script.
// This is crucial for performance and preventing UI freezes.
// For production, consider serving pdf.worker.min.mjs from a CDN or your static assets.
pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`;
async function renderPdfToCanvas(pdfUrl, canvasId) {
const canvas = document.getElementById(canvasId);
if (!canvas) {
console.error(`Canvas element with ID '${canvasId}' not found.`);
return;
}
const context = canvas.getContext('2d');
try {
// Asynchronously downloads PDF
const loadingTask = pdfjsLib.getDocument(pdfUrl);
const pdf = await loadingTask.promise;
// Fetch the first page
const pageNumber = 1;
const page = await pdf.getPage(pageNumber);
const scale = 1.5;
const viewport = page.getViewport({ scale });
// Support HiDPI-screens.
const outputScale = window.devicePixelRatio || 1;
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
canvas.style.width = Math.floor(viewport.width) + 'px';
canvas.style.height = Math.floor(viewport.height) + 'px';
const transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
// Render PDF page into canvas context
const renderContext = {
canvasContext: context,
transform,
viewport,
};
await page.render(renderContext).promise;
console.log(`Page ${pageNumber} rendered to canvas successfully.`);
} catch (error) {
console.error('Error rendering PDF:', error);
}
}
// Example usage: Make sure you have a <canvas id="pdf-render-canvas"></canvas> in your HTML
// And a PDF file accessible at this URL (e.g., in your public folder)
const samplePdfUrl = 'https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf';
renderPdfToCanvas(samplePdfUrl, 'pdf-render-canvas');
/* Example HTML structure:
<!DOCTYPE html>
<html>
<head>
<title>PDF.js Quickstart</title>
</head>
<body>
<h1>PDF Viewer</h1>
<canvas id="pdf-render-canvas" style="border: 1px solid black;"></canvas>
<script type="module" src="./your-script.js"></script>
</body>
</html>
*/