# How to Use the `@firecrawl/pdf-inspector` Node.js Bindings: Complete Guide

> Master the @firecrawl/pdf-inspector Node.js bindings. This guide shows how to leverage the powerful Rust PDF engine via TypeScript/JavaScript for fast sync and async PDF processing.

- Repository: [Firecrawl/pdf-inspector](https://github.com/firecrawl/pdf-inspector)
- Tags: how-to-guide
- Published: 2026-08-31

---

**The `@firecrawl/pdf-inspector` package provides native Node.js bindings that expose the full Rust PDF engine through TypeScript/JavaScript, with both synchronous APIs for quick operations and asynchronous APIs for CPU-intensive PDF processing.**

This guide walks through the practical use of `pdf-inspector` Node.js bindings built with [napi-rs](https://napi.rs). The binding layer in [`napi/src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/src/lib.rs) generates automatic TypeScript definitions from annotated Rust code, giving you type-safe access to PDF classification, OCR, and region-based extraction without managing a Rust toolchain.

## Installation and Setup

Pre-built binaries are distributed for every major platform through `optionalDependencies` in [`napi/package.json`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/package.json). A standard npm install pulls the correct binary automatically.

```bash
npm install @firecrawl/pdf-inspector

```

No additional build tools required. The package exports all public symbols from [`index.js`](https://github.com/firecrawl/pdf-inspector/blob/main/index.js) with full type definitions in [`index.d.ts`](https://github.com/firecrawl/pdf-inspector/blob/main/index.d.ts).

## Core API Patterns

The `pdf-inspector` Node.js bindings follow two execution patterns defined in [`napi/src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/src/lib.rs):

- **Synchronous functions** — Run on the Node event loop, ideal for lightweight operations like PDF classification
- **Asynchronous functions** — Execute on the libuv thread pool via `Task` structs, keeping the event loop responsive during heavy OCR or multi-page processing

### Synchronous vs. Asynchronous Methods

| Pattern | Functions | Use Case |
|---------|-----------|----------|
| Sync | `classifyPdf`, `extractTextInRegions`, `extractTablesInRegions` | Quick checks, small PDFs |
| Async | `processPdfAsync`, `classifyPdfAsync` | Large files, GPU OCR, production servers |

## PDF Classification (Synchronous)

The `classifyPdf` function inspects a PDF buffer and returns type metadata without full processing. This is implemented in [`napi/src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/src/lib.rs) as a thin `#[napi]` wrapper around `classify_pdf_impl`.

```typescript
import { classifyPdf } from '@firecrawl/pdf-inspector';
import { readFileSync } from 'fs';

const pdf = readFileSync('document.pdf');

// Synchronous classification — runs on event loop
const classification = classifyPdf(pdf);

console.log(classification.pdfType);
// "TextBased" | "Scanned" | "Mixed" | "ImageBased"

console.log(classification.pagesNeedingOcr);
// number[] — 0-based page indices requiring OCR

```

## Full PDF Processing with OCR (Asynchronous)

For complete PDF-to-Markdown conversion with selective OCR, use `processPdfAsync`. This creates a `ProcessPdfTask` struct that copies the `Buffer` into `Vec<u8>` and executes on the thread pool.

```typescript
import { processPdfAsync, OcrMode, type PdfResult } from '@firecrawl/pdf-inspector';

async function convertPdf(pdfBuffer: Buffer) {
  const result: PdfResult = await processPdfAsync(pdfBuffer, {
    mode: OcrMode.Selective,      // Only OCR pages that need it
    dpi: 300,                      // Render resolution for OCR
    pageNumbers: [0, 1, 2],        // Optional subset of pages
    offline: true,                 // Skip model downloads
  });

  console.log('Markdown length:', result.markdown?.length ?? 0);
  console.log('Pages with tables:', result.pagesWithTables);
  console.log('OCR provenance:', result.ocrPages);
  // Array of OcrPageProvenance with per-page OCR flags
}

```

The `OcrOptions` struct converts to internal `pdf_inspector::vision::OcrPdfOptions` via `to_core_ocr_options` in the binding layer.

## Region-Based Text and Table Extraction

For targeted extraction from specific page regions — useful in hybrid OCR pipelines — pass arrays of `PageRegions`. The helper `parse_page_regions` in [`napi/src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/src/lib.rs) converts these to the Rust representation used by `extract_text_in_regions_mem`.

```typescript
import { extractTextInRegions, type PageRegions } from '@firecrawl/pdf-inspector';

const regions: PageRegions[] = [
  {
    page: 0, // 0-based page index
    regions: [
      [0, 0, 300, 400],      // bbox: [left, top, right, bottom] in PDF points
      [300, 0, 612, 400],    // second region on same page
    ],
  },
  {
    page: 2,
    regions: [[0, 0, 612, 792]], // Full page 2
  },
];

const regionResults = extractTextInRegions(pdfBuffer, regions);

regionResults.forEach((pageResult) => {
  pageResult.regions.forEach((region) => {
    if (region.needsOcr) {
      // Fall back to GPU OCR only when necessary
      console.log(`Page ${pageResult.page} region needs OCR: ${region.ocrReason}`);
    } else {
      console.log(`Extracted: ${region.text}`);
    }
  });
});

```

Each region returns a `needsOcr` flag with an `ocrReason` string for pipeline decision-making.

## Type Definitions and Editor Support

All TypeScript definitions are auto-generated from `#[napi(...)]` annotations in [`napi/src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/src/lib.rs). Key exported types include:

```typescript
// Enums
OcrMode: 'Selective' | 'Forced' | 'Disabled'

// Result types
PdfResult: {
  markdown?: string;
  pagesWithTables: number[];
  ocrPages: OcrPageProvenance[];
}

// Region types  
PageRegions: {
  page: number;
  regions: Array<[number, number, number, number]>;
}

RegionResult: {
  bbox: [number, number, number, number];
  text: string;
  needsOcr: boolean;
  ocrReason?: string;
}

```

## Architecture Reference

Understanding the source structure helps with debugging and advanced usage:

| Path | Purpose |
|------|---------|
| [`napi/src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/src/lib.rs) | NAPI binding layer — enums, structs, sync/async functions, conversion helpers |
| [`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs) | Core Rust PDF processing, classification, OCR routing |
| `src/vision/*` | PDFium rendering, ONNX Runtime OCR, model downloads |
| `src/extractor/*` | Text extraction, position handling, structure-tree utilities |

All NAPI functions delegate to implementations in the `src/` directory. Async variants wrap these in `Task` structs for thread pool execution.

## Summary

- Install with `npm install @firecrawl/pdf-inspector` — pre-built binaries require no Rust toolchain
- Use **synchronous APIs** (`classifyPdf`, `extractTextInRegions`) for quick, lightweight operations
- Use **asynchronous APIs** (`processPdfAsync`) to keep the event loop responsive during OCR
- Control OCR behavior through `OcrOptions` with `mode`, `pageNumbers`, `dpi`, and `offline` parameters
- Extract from specific regions with `PageRegions` arrays and check `needsOcr` flags for hybrid pipelines
- Type definitions are auto-generated from [`napi/src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/src/lib.rs) and fully supported in [`index.d.ts`](https://github.com/firecrawl/pdf-inspector/blob/main/index.d.ts)

## Frequently Asked Questions

### What Node.js versions are supported?

The napi-rs build in [`napi/src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/src/lib.rs) targets N-API version guarantees. Pre-built binaries cover Node.js 16, 18, 20, and 22 across Windows, macOS, and Linux (x64 and ARM64). Check [`napi/package.json`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/package.json) for the specific `napi` version used in your installed release.

### Can I use this with Bun or Deno?

The package exports standard CommonJS and ESM modules from [`index.js`](https://github.com/firecrawl/pdf-inspector/blob/main/index.js). Bun compatibility has been tested; Deno requires Node.js compatibility mode. The napi-rs native addon loads through standard Node-API interfaces that alternative runtimes increasingly support.

### How do I handle PDFs that fail classification?

`classifyPdf` returns `PdfType` classification and an array of pages needing OCR. For edge cases, fall back to `processPdfAsync` with `OcrMode.Forced` to bypass classification heuristics and run OCR on all pages, or inspect `pagesNeedingOcr` and process those pages individually through region-based extraction.

### Why does my async function hang?

Ensure you're `await`-ing `processPdfAsync` or handling the returned `Promise`. The `Task` implementation in [`napi/src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/napi/src/lib.rs) moves the PDF buffer to a thread pool worker—if the main thread blocks waiting for completion without proper async handling, the event loop stalls. Always use `await` or `.then()` in async contexts.