Skip to content

API Reference

@scaryterry/pdfium


High-Performance Universal PDFium bindings for Browser and Node.js.

  • Hybrid Architecture - Use Native bindings (C++) on Node.js for maximum speed, or WASM on browsers for portability.
  • Zero dependencies - PDFium WASM is bundled; Native bindings are optional.
  • Type-safe - Full TypeScript support with branded types and strict mode
  • Automatic resource cleanup - Symbol.dispose support (using keyword)
  • Typed exceptions - Error subclasses with error codes for precise handling
  • Universal - Works in Node.js 22+ and modern browsers
  • ESM-only - Modern ES2024 module format
  • Worker support - Off-main-thread processing via WorkerProxy
Terminal window
pnpm add @scaryterry/pdfium
import { PDFium } from '@scaryterry/pdfium';
// Initialise the library
using pdfium = await PDFium.init();
// Open a PDF document
using document = await pdfium.openDocument(pdfBytes);
console.log(`Document has ${document.pageCount} pages`);
// Iterate over pages
for (const page of document.pages()) {
using p = page;
// Get page dimensions
const { width, height } = p.size;
console.log(`Page ${p.index}: ${width}x${height} points`);
// Extract text
const text = p.getText();
console.log(text);
// Render to RGBA bitmap
const { data, width: renderWidth, height: renderHeight } = p.render({ scale: 2 });
// data is a Uint8Array of RGBA pixels
}

All operations throw typed error subclasses on failure:

import { PDFium, DocumentError } from '@scaryterry/pdfium';
try {
using pdfium = await PDFium.init();
using document = await pdfium.openDocument(corruptBytes);
} catch (error) {
if (error instanceof DocumentError) {
console.error(error.code); // numeric error code
console.error(error.message); // human-readable message
console.error(error.context); // optional context data
}
}

The main entry point for the library.

MethodReturnsDescription
PDFium.init(options?)Promise<PDFium>Initialise the library
pdfium.openDocument(data, options?)Promise<PDFiumDocument>Open a PDF document
pdfium.createDocument()PDFiumDocumentBuilderCreate a new PDF document
pdfium.createProgressiveLoader(data)ProgressivePDFLoaderCreate a progressive loader for linearised PDFs

Represents a loaded PDF document.

Property/MethodReturnsDescription
document.pageCountnumberNumber of pages
document.getPage(index)PDFiumPageLoad a page by index
document.pages()Generator<PDFiumPage>Iterate all pages
document.save(options?)Uint8ArraySerialise the document to bytes
document.getBookmarks()Bookmark[]Extract the bookmark tree
document.attachmentCountnumberNumber of file attachments
document.getAttachments()PDFAttachment[]Extract file attachments
document.importPages(source, options?)voidImport pages from another document
document.createNUpDocument(options)PDFiumDocumentCreate N-up layout document

Represents a single page in a PDF document.

Property/MethodReturnsDescription
page.indexnumberZero-based page index
page.sizePageSizePage dimensions in points
page.widthnumberPage width in points
page.heightnumberPage height in points
page.rotationPageRotationPage rotation (0, 90, 180, 270)
page.objectCountnumberNumber of objects on the page
page.annotationCountnumberNumber of annotations on the page
page.render(options?)RenderResultRender to RGBA bitmap
page.getText()stringExtract all text content
page.getObjects()PageObject[]Get page objects (text, images, paths)
page.objects()IterableIterator<PageObject>Lazy page object iterator
page.getAnnotation(index)AnnotationGet annotation by index
page.getAnnotations()Annotation[]Get all annotations
page.findText(query, flags?)Generator<TextSearchResult>Search for text with positions
page.getCharBox(charIndex)CharBox | undefinedGet character bounding box
page.getCharIndexAtPos(x, y)numberGet character index at position
page.getTextInRect(l, t, r, b)stringGet text within a rectangle
page.getCharacterInfo(index)CharacterInfoGet detailed character info
page.getStructureTree()StructureElement[] | undefinedGet accessibility structure tree

Creates new PDF documents from scratch.

Property/MethodReturnsDescription
builder.pageCountnumberNumber of pages added
builder.addPage(options?)PDFiumPageBuilderAdd a new page
builder.deletePage(index)voidDelete a page by index
builder.loadStandardFont(name)FontHandleLoad a standard PDF font
builder.save(options?)Uint8ArraySerialise the document to bytes

Detects linearisation and supports incremental loading.

Property/MethodReturnsDescription
loader.isLinearisedbooleanWhether the document is linearised
loader.linearisationStatusLinearisationStatusDetailed linearisation status
loader.isDocumentAvailablebooleanWhether all document data is available
loader.isPageAvailable(index)booleanWhether a specific page is available
loader.firstPageNumbernumberFirst available page number
loader.getDocument(password?)PDFiumDocumentExtract the loaded document
interface RenderOptions {
scale?: number; // Scale factor (default: 1)
width?: number; // Target width in pixels (overrides scale)
height?: number; // Target height in pixels (overrides scale)
renderFormFields?: boolean; // Include form fields (default: false)
backgroundColour?: number; // ARGB integer (default: 0xFFFFFFFF)
rotation?: PageRotation; // Rotation to apply (default: None)
}
Error ClassThrown ByDescription
InitialisationErrorPDFium.init()WASM load or library init failure
DocumentErrorpdfium.openDocument()Invalid format, password, file not found
PageErrordocument.getPage()Page not found, load failure, out of range
RenderErrorpage.render()Bitmap creation failure, invalid dimensions
TextErrorpage.getText()Text extraction or text page load failure
MemoryErrorInternalWASM memory allocation failure
WorkerErrorWorkerProxyWorker creation or communication failure
RangeCategoryExamples
1xxInitialisationWASM load failure, library init failure
2xxDocumentInvalid format, password required, file not found
3xxPagePage not found, load failure, out of range
4xxRenderBitmap creation failure, invalid dimensions
5xxMemoryAllocation failure, buffer overflow
6xxTextExtraction failure, text page load failure
7xxObjectUnknown type, access failure
8xxWorkerCreation failure, communication error, timeout

All PDFium resources implement Symbol.dispose for automatic cleanup:

// Recommended: using keyword (automatic cleanup)
{
using page = document.getPage(0);
// page is automatically disposed when scope exits
}
// Alternative: explicit dispose
const page = document.getPage(0);
try {
// use page
} finally {
page.dispose();
}

A FinalizationRegistry provides a safety net - if a resource is garbage collected without being disposed, a warning is logged in development mode.

In browser environments, provide the WASM binary explicitly:

import { PDFium } from '@scaryterry/pdfium';
// Option 1: Load from URL (recommended)
using pdfium = await PDFium.init({
wasmUrl: '/pdfium.wasm'
});
// Option 2: Pre-load binary
const wasmResponse = await fetch('/pdfium.wasm');
const wasmBinary = await wasmResponse.arrayBuffer();
using pdfium = await PDFium.init({ wasmBinary });

For off-main-thread processing:

import { PDFium } from '@scaryterry/pdfium';
await using pdfium = await PDFium.init({
useWorker: true,
workerUrl: '/worker.js',
wasmUrl: '/pdfium.wasm',
});
await using document = await pdfium.openDocument(pdfArrayBuffer);
const result = await document.renderPage(0, { scale: 2 });

Need low-level control? Use WorkerProxy directly with openDocument() -> loadPage() -> renderPage() -> closePage().

For optimal performance in Node.js, use the native backend:

import { PDFium } from '@scaryterry/pdfium';
// Attempt native, fall back to WASM
const pdfium = await PDFium.init({ useNative: true });

Install platform-specific packages:

Terminal window
pnpm add @scaryterry/pdfium-darwin-arm64 # macOS Apple Silicon
pnpm add @scaryterry/pdfium-darwin-x64 # macOS Intel
pnpm add @scaryterry/pdfium-linux-x64-gnu # Linux x64
pnpm add @scaryterry/pdfium-linux-arm64-gnu # Linux ARM64
pnpm add @scaryterry/pdfium-win32-x64-msvc # Windows x64

The native backend provides faster performance by eliminating WASM marshalling overhead. See the documentation for details on backend selection and feature coverage.

  • Node.js: >= 22 LTS
  • Browsers: Chrome 117+, Firefox 104+, Safari 16.4+
  • Module format: ESM only

MIT