← Back to Blog
Guides

PDF Parsing in Node.js: A Complete Technical Guide (June 2026)

Learn how to use pdf-parse v2 in Node.js for text, tables, images, browser and Next.js workflows, plus when a vision-first parser is a better fit.

Aman Mishra
Aman Mishra
9 min read
PDF Parsing in Node.js: A Complete Technical Guide (June 2026)

pdf-parse extracts text from a clean, digital-native PDF with little code. On scanned files, multi-column reports, or tables, the result can be empty or lose the layout your pipeline needs.

This guide uses Node.js 20.16 or newer and pdf-parse v2. You'll build a runnable script for text extraction, learn how to request metadata, selected pages, images, and tables, and decide when a document needs OCR or layout-aware parsing instead.

TLDR:

  • pdf-parse extracts text, document information, embedded images, and detected tables from PDFs.
  • Requires Node.js 20.16.0+, 22.3.0+, 23.0.0+, or 24.0.0+ for its documented Node.js support.
  • getText() is not OCR, and text-only output may not retain the structure your application needs.
  • Start with getText(), then add getInfo(), getImage(), or getTable() only when your output contract needs them.
  • Unsiloed AI can return confidence and bounding-box information in its parsing responses.

What Is pdf-parse and When Should You Use It?

pdf-parse is a JavaScript/TypeScript package built on pdf.js. Its current API can extract text and document information, and also exposes image and table extraction methods. You can provide PDF data as a buffer or a URL.

It suits the following uses:

  • Extracting text from digital-native PDFs.
  • Batch processing documents in a Node.js pipeline.
  • Reading metadata such as author and creation date.

The library has real limits worth knowing before you build around it:

  • pdf-parse does not perform OCR. A scan without a usable text layer needs OCR or another vision-based preprocessing step.
  • getText() returns text rather than a guaranteed semantic representation of rows, columns, lists, or headings. Test it on the layouts your application receives.
  • The package provides getTable() and getImage() for table and embedded-image workflows. Evaluate their output on representative documents rather than assuming text extraction will reconstruct every layout.

Build and Run a pdf-parse Extractor

The next three steps are sequential. Complete them in order to create the project, build a local text extractor, and check its output against a representative PDF.

Step 1: Create the Node.js Project

Set up the project: Create a project directory and install pdf-parse with npm:

Bash
mkdir pdf-parse-demo
cd pdf-parse-demo
npm init -y
npm install pdf-parse

Check your runtime: Before building a production pipeline, confirm that your runtime is supported. Per the pdf-parse npm documentation, supported versions are 20.16.0+, 22.3.0+, 23.0.0+, and 24.0.0+. Versions 21.x, 19.x, and anything earlier are unsupported.

Add test files: Copy a representative digital-native PDF into the project directory as document.pdf. Keep at least one scan and one layout-heavy document for the validation workflow later in this guide.

Step 2: Extract Text From a Local PDF

The v2 API uses the PDFParse class rather than a bare function call. Its parsing methods are asynchronous, so use promises or async/await throughout.

Create the script: Create parse-local.mjs in the project directory:

JavaScript
import { readFile } from "node:fs/promises";
import { PDFParse } from "pdf-parse";

async function extractText(filePath) {
  const buffer = await readFile(filePath);
  const parser = new PDFParse({ data: buffer });

  try {
    const result = await parser.getText();
    console.log(`Pages: ${result.total}`);
    console.log(result.text);
  } finally {
    await parser.destroy();
  }
}

const filePath = process.argv[2] ?? "./document.pdf";
await extractText(filePath);

Step 3: Run and Validate the Extractor

The first run establishes whether flat text is sufficient for the document and downstream task you care about.

Run it: Run the script against the PDF you copied into the project:

Bash
node parse-local.mjs ./document.pdf

The script prints the parsed page count followed by the extracted text. If the output is empty, out of reading order, or missing the structure your application needs, don't try to repair it with string splitting yet. Test the table method or route the file to OCR or layout-aware parsing. For PDF to JSON conversion, text output is often only a starting point.

Adapt the Extractor for Other Inputs and Outputs

Each subsection below is an independent variation on the working local extractor from Step 2. Start from the original parse-local.mjs each time rather than applying these changes one after another.

The available methods cover text and selected pages, metadata, embedded images, and detected tables. The diagram shows how those outputs branch from the same parser instance.

A PDF enters the PDFParse object and fans out to getText for text and selected pages, getInfo for metadata, getImage for embedded images, and getTable for detected tables. A boundary notes that pdf-parse does not perform OCR and that layout-sensitive output needs testing.

Parse a PDF From a Remote URL

Create the URL variant: Create parse-remote.mjs when the PDF is available through a URL:

JavaScript
import { PDFParse } from "pdf-parse";

async function extractFromUrl(url) {
  const parser = new PDFParse({ url });

  try {
    const result = await parser.getText();
    console.log(`Pages: ${result.total}`);
    console.log(result.text);
  } finally {
    await parser.destroy();
  }
}

const url = process.argv[2];
if (!url) throw new Error("Pass a PDF URL as the first argument");
await extractFromUrl(url);

Run it: Pass a direct PDF URL:

Bash
node parse-remote.mjs https://bitcoin.org/bitcoin.pdf

The remote server must allow the request and return PDF data. For untrusted URLs, validate the host, response size, and content type before parsing.

Inspect PDF Metadata

The getInfo() method returns document information. Common fields include Title, Author, Creator, and Producer, though these values are supplied by the authoring tool and may be empty.

Modify the local script: In parse-local.mjs, replace the getText() call and both output lines with:

JavaScript
const result = await parser.getInfo();
const { Title, Author, Creator, Producer } = result.info ?? {};
console.log({ Title, Author, Creator, Producer });

Keep the existing try and finally blocks so the parser is always destroyed.

Extract Selected Pages With getText()

Modify the local script: In parse-local.mjs, replace the getText() call and its output lines with the following code to extract pages 1 and 3:

JavaScript
const result = await parser.getText({ partial: [1, 3] });
console.log(result.text);

The partial array uses one-based page numbers. Use getText() without partial when you need the full document. The current v2 API does not use the legacy pagerender callback.

Extract Embedded Images

PDFs can store images as raw binary streams, so text extraction does not expose them. pdf-parse v2 provides getImage() for embedded-image extraction and returns images by page. Use an image threshold to exclude small decorative images when appropriate.

Modify the local script: In parse-local.mjs, replace the getText() call and its output lines with:

JavaScript
const result = await parser.getImage({ imageThreshold: 80 });
for (const page of result.pages) {
  console.log(`Page ${page.pageNumber}: ${page.images.length} images`);
}

This reports image counts without printing image buffers or base64 data to the terminal. Lower imageThreshold only when the default excludes an image your application needs.

Extract Tables

PDFs can store tables as visually formatted text with no semantic structure, so text extraction can lose or scramble them. The getText() method does not promise a semantic table model. pdf-parse v2 also provides getTable() for detected tables. Verify it against your files, especially where tables have merged cells or spanning headers.

Modify the local script: In parse-local.mjs, replace the getText() call and its output lines with:

JavaScript
const result = await parser.getTable();
for (const page of result.pages) {
  console.log(`Page ${page.num}`);
  console.dir(page.tables, { depth: null });
}

Compare the resulting rows and columns with the source PDF. A successful method call does not prove that merged cells, spanning headers, or multi-page tables were reconstructed correctly.

When a text-only result is not sufficient, options include:

  • Coordinate-based reconstruction: group positioned spans by Y-axis position and infer columns from X-axis gaps.
  • Heuristic line detection: infer rows from horizontal whitespace gaps.
  • Vision-based parsing: identify the table visually and evaluate its output on representative files.

For varied production documents, test whether the output preserves the information your downstream application needs, including coordinates, reading order, and table boundaries.

Run a Separate Browser Proof of Concept

Browser support is a separate deployment path, not the next change to the Node.js script. pdf-parse v2 supports CJS and ESM in Node.js and the browser, but the browser build needs its matching worker.

Create the Browser Entry Point

Create the browser files: Create index.html and place document.pdf beside it. This example pins the package to major version 2 and configures the matching worker:

HTML
<pre id="output">Parsing…</pre>

<script type="module">
import { PDFParse } from "https://cdn.jsdelivr.net/npm/pdf-parse@2/dist/pdf-parse/web/pdf-parse.es.js";

PDFParse.setWorker(
  "https://cdn.jsdelivr.net/npm/pdf-parse@2/dist/pdf-parse/web/pdf.worker.mjs",
);

const parser = new PDFParse({ url: "/document.pdf" });
try {
  const result = await parser.getText();
  document.querySelector("#output").textContent = result.text;
} finally {
  await parser.destroy();
}
</script>

Serve the Browser Example Over HTTP

Run it: Serve the directory over HTTP rather than opening the file directly:

Bash
npx --yes serve .

Open the local URL printed by serve. For production, install and bundle the web build instead of depending on a public CDN at runtime.

Plan for Production Runtimes

For a Next.js application, test the selected Node or web build in the exact route/runtime you deploy. Do not rely on a generic webpack externalization rule as a substitute for that test.

Deployment considerations:

  • The pdf-parse documentation lists Next.js + Vercel, AWS Lambda, Netlify, and Cloudflare Workers among supported targets.
  • Vercel's Node.js runtime provides Node.js APIs. Check its bundle limits for your deployment.
  • AWS Lambda has deployment-package limits, so account for the complete bundle, layers, and runtime dependencies.

Recommended Workflow for Reliable PDF Extraction

Use a representative test set before you choose a parser or ship a pipeline:

  1. Start with the simplest contract. Run getText() on a digital-native PDF and confirm that the text and page count match the source.
  2. Test the structure you consume. If your application reads tables or images, run getTable() or getImage() and compare the returned elements with the PDF. Do not infer success from a nonempty response.
  3. Define acceptance checks. Record expected pages, headings, table columns, required fields, and failure conditions for each document class.
  4. Route failures deliberately. Send scans to OCR. Send documents where position or reading order changes the answer to a layout-aware or vision parser.
  5. Measure on production-shaped documents. Benchmark accuracy, latency, memory, and error handling on the same layouts and file sizes your application receives.

Use pdf-parse when its output passes those checks. Choose a different parser when fixing its output would require layout reconstruction, OCR, or document-specific string heuristics.

Comparing pdf-parse with pdf2json and Similar Packages

Each JavaScript PDF library has a different tradeoff.

Library Best For Key Tradeoff
pdf-parse Text, document information, embedded images, and detected tables Does not perform OCR; validate extraction quality on your PDFs
pdf2json Converting PDF text and interactive form elements to JSON for Node.js/server-side processing Choose it when its JSON-oriented output fits your workflow
pdfjs-dist Building a PDF viewer or using the PDF.js display layer Lower-level display APIs require more integration work than a text-only wrapper
pdfreader Callback-driven PDF items with text and x/y coordinates; rule-based table parsing Consumers assemble the emitted items into their own data structure
pdf-parse-new A package that documents worker-thread and child-process parsing strategies Treat its performance statements as package self-reports and benchmark your workload

Choose pdf-parse for text extraction from clean, digitally generated PDFs. Review document parsing software options when you need OCR or layout-aware extraction.

Troubleshooting pdf-parse in Node.js

The following configuration and input failures have direct fixes.

For a custom browser build, configure the web worker with PDFParse.setWorker() as shown in the package documentation. Use the worker file that matches the build you ship.

Password-protected PDFs can be supplied with a password load parameter. Handle PasswordException, and always call destroy() in finally to release parser resources.

These practices reduce unnecessary processing and make failures easier to diagnose:

  • Use partial with getText() when you only need selected pages, rather than parsing the full document by default.
  • Catch parser errors such as invalid-PDF, password, format, response, and abort errors, then log enough context to reproduce the failing input.
  • Keep v2 imports on the documented pdf-parse package entry point; do not use the legacy pdf-parse/lib/pdf-parse.js path.

Vision-First Parsing for Production Document Pipelines

Use a vision-first parser when your documents need layout, table, or scanned-page handling.

A comparison recommends pdf-parse v2 when a PDF has a usable text layer and content matters more than position, and a vision or OCR pipeline when visual structure carries meaning.

Unsiloed AI can return page-numbered segments with segment-level confidence and bbox values from its /parse endpoint, alongside OCR word entries that include text, confidence, and bbox. In a live check on 2026-08-07, its /v2/extract endpoint returned each requested schema field as a value with grounding_score and extraction_score. Citations were null for that test. Treat citations and bounding boxes as response fields to inspect for your endpoint and document, not universal per-field guarantees. See text extraction and structured document data extraction for related implementation context.

For a deeper comparison, see the document parser tools comparison.

When to Choose pdf-parse for Node.js Projects

pdf-parse is a good fit for Node.js projects when its text, metadata, image, or table methods produce the output your PDFs require. For scans and layout-sensitive workflows, book a demo to evaluate vision-first parsing on representative documents.

FAQ

The following answers address common pdf-parse implementation questions.

Can I use pdf-parse for scanned PDFs?

pdf-parse alone does not perform OCR, so a scanned document without a usable text layer needs an OCR or vision-based preprocessing step before text extraction can be reliable.

How do I extract table structure from PDFs in Node.js?

Use getTable() in current pdf-parse v2 when detected-table output suits your documents, and test it against merged cells, spanning headers, and multi-page tables. getText() is text output rather than a guaranteed semantic table model. When the result is not adequate, coordinate-based reconstruction or a vision-based parser are alternatives to evaluate on your representative files.

Does pdf-parse work in Next.js API routes?

Yes. pdf-parse documents Next.js + Vercel as a supported target. Use the Node or web build appropriate to the route/runtime, configure a web worker for browser use, and test the deployed bundle with the PDFs your application accepts.

What is the difference between pdf-parse and pdfjs-dist?

pdf-parse provides a higher-level API for text, document information, images, and detected tables. pdfjs-dist is the PDF.js distribution used when you need its viewer or display-layer capabilities. Choose based on the output and integration surface you need, then measure the resulting bundle for the version you deploy.

How do I choose a document processing solution with low error rates?

Error rates depend on document structure, the selected extraction method, and how you validate results. Test text, table, image, OCR, and vision-based approaches against representative documents and define acceptance checks for the fields your workflow uses. When confidence, locations, or citations are important, inspect the actual API response for the endpoint and document type you plan to deploy.

Continue reading