node-poppler

An asynchronous Node.js wrapper around the Poppler PDF rendering utilities for converting, splitting, merging, and inspecting PDF files.

Library
npm
v11.0.0
249stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
81/100Excellent
Development Activity92
Maintenance100
Community52
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture82
Code Quality96
Innovation78
Learning Curve65

node-poppler wraps the Poppler command-line utilities (pdftocairo, pdftohtml, pdftoppm, pdftops, pdftotext, pdfinfo, pdfimages, pdffonts, pdfattach, pdfdetach, pdfseparate, pdfunite) behind a single async/await-friendly Poppler class, so Node.js applications can convert, inspect, and manipulate PDF files without shelling out to child_process themselves.

Each Poppler binary is exposed as a class method (pdfToCairo, pdfToHtml, pdfToText, pdfToPpm, pdfToPs, pdfInfo, pdfImages, pdfFonts, pdfAttach, pdfDetach, pdfSeparate, pdfUnite) that accepts either a file path or an in-memory Buffer, validates its options object against a per-binary schema (including the minimum Poppler version an option requires), and returns a promise that resolves with stdout or rejects with a descriptive Error. This removes the need to hand-build CLI argument arrays or parse raw stderr codes.

It ships as CommonJS with bundled TypeScript type definitions, and on Windows automatically falls back to an optional node-poppler-win32 dependency that bundles prebuilt binaries, while Linux/macOS users install poppler-utils themselves.

What You Get

  • A single Poppler class exposing one method per Poppler binary (pdfToCairo, pdfToHtml, pdfToPpm, pdfToPs, pdfToText, pdfInfo, pdfImages, pdfFonts, pdfAttach, pdfDetach, pdfSeparate, pdfUnite)
  • Accepts either a file path or an in-memory Buffer as input, with automatic stdin piping for Buffers
  • Per-option validation against each binary’s accepted arguments, including minimum/maximum Poppler version checks so unsupported flags fail fast with a clear error
  • AbortSignal support on every method for cancelling in-flight conversions
  • Bundled TypeScript type definitions and full JSDoc for editor autocomplete without a separate @types package
  • Automatic Windows binary resolution via the optional node-poppler-win32 dependency, falling back to a user-supplied binary path or PATH lookup on Linux/macOS

Common Use Cases

  • Converting uploaded PDFs to PNG/JPEG thumbnails for a document management or preview UI
  • Extracting plain text from PDFs for full-text search indexing or LLM ingestion pipelines
  • Merging multiple generated PDF reports into a single downloadable file
  • Splitting a multi-page PDF into individual per-page files for downstream processing
  • Reading PDF metadata (page count, dimensions, permissions) before running expensive operations
  • Extracting or attaching embedded files inside PDF containers

Under The Hood

Architecture index.js exports a single Poppler class holding private fields for each resolved binary path plus two caches (#binVersions, #acceptedOptions). Every public method (pdfToCairo, pdfToText, pdfInfo, etc.) follows the same two-stage pipeline: parseOptions() validates the caller’s options object against a per-binary schema (checking type and, via semver comparison, whether the installed Poppler version actually supports the flag) and produces a CLI argument array terminated with an end-of-options -- marker; execBinary() then spawns the binary, pipes a Buffer over stdin or lets it read a filepath directly, and collects stdout/stderr concurrently with Promise.all. This is a facade over child_process — no caller ever touches spawn directly — so a change to execBinary()’s contract would ripple through all twelve public methods that depend on it.

Tech Stack Plain JavaScript with JSDoc-driven types (TypeScript declarations are emitted separately via tsc -p tsconfig.build.json; no build step is needed to run the library, since main points straight at src/index.js). Runtime dependencies are deliberately minimal: camelcase formats keys for pdfInfo’s JSON output, ice-barrage deep-freezes the accepted-options maps, and semver powers the minVersion/maxVersion gating. An optional dependency, node-poppler-win32, supplies prebuilt Windows binaries so Windows users skip a separate poppler-utils install. Tooling is a modern JS stack: ESLint plus Prettier for style, Jest for tests with coverage thresholds enforced directly in package.json, commitlint for conventional commits, and licensee for dependency license auditing.

Code Quality The test suite exceeds 1,600 lines and mocks child_process to exercise specific exit codes, stdout/stderr combinations, and AbortSignal cancellation, while also running real fixture PDFs through the binaries for integration-level coverage. Error handling is explicit rather than swallowed: known Poppler exit codes map to human-readable messages via a lookup table, and invalid options throw immediately with a joined list of specific messages. Naming is consistent camelCase mirroring each binary’s long-form flags, private class fields prevent external mutation of resolved binary paths, and CI runs lint, typecheck, and coverage-gated tests on every push alongside CodeQL and OSSF Scorecard supply-chain scanning.

API Design The most distinctive choice is per-option, per-binary-version validation: each option schema carries an explicit minimum (and sometimes maximum) supported Poppler version, so calling a flag introduced in a newer Poppler release than what’s installed throws a specific, actionable error rather than failing silently or surfacing a cryptic native CLI error. Combined with transparent Buffer/stdin support and the -- end-of-options guard against hyphen-prefixed filenames being misread as flags, the API absorbs several common child_process footguns that thinner CLI wrappers leave to the caller — a refinement of an established wrapper pattern rather than a wholly new capability.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search