unpdf

Extract text, links, images, and metadata from PDFs in Node.js, browsers, and serverless edge runtimes.

Library
npm
v1.8.1
1,227stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
76/100Good
Development Activity76
Maintenance88
Community48
Maturity52
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture85
Code Quality88
Innovation78
Learning Curve55

unpdf is a lightweight utility library built around Mozilla’s PDF.js that works consistently across every JavaScript runtime — Node.js, Deno, Bun, browsers, and edge platforms like Cloudflare Workers. Rather than requiring consumers to wrangle PDF.js’s browser-oriented API and worker-loading assumptions, unpdf ships a serverless build with the worker inlined and browser-only globals polyfilled, so getDocument and the rest of the PDF.js API work unmodified in environments that can’t load separate worker files or don’t have a DOM.

On top of that serverless PDF.js build, unpdf exposes a small set of high-level functions — extractText, extractTextItems, extractLinks, extractImages, getMeta, and renderPageAsImage — that cover the extraction and rendering tasks most PDF-processing code actually needs, particularly for AI applications that summarize or analyze uploaded documents. Consumers who need the raw PDF.js API, or want to swap in the official build instead of the bundled serverless one, can drop down via getResolvedPDFJS or definePDFJSModule without changing any call sites.

What You Get

  • Serverless PDF.js build - A pre-bundled, worker-inlined build of PDF.js with browser-only globals polyfilled, so it runs in Cloudflare Workers and other edge runtimes with no separate worker file needed.
  • Text extraction with and without layout - extractText for plain text (optionally merged across pages) and extractTextItems for positioned text items with coordinates, font size, and reading direction.
  • Link and image extraction - extractLinks pulls every hyperlink from a document; extractImages returns raw pixel data, dimensions, and channel info per page.
  • Metadata extraction - getMeta reads a PDF’s info and metadata dictionaries, with optional date parsing into Date objects.
  • Page-to-image rendering - renderPageAsImage renders a page to an ArrayBuffer or data URL via @napi-rs/canvas, for thumbnailing or visual diffing.
  • Drop-in swap to official PDF.js - definePDFJSModule lets you replace the bundled serverless build with pdfjs-dist or a legacy version without touching call sites.

Common Use Cases

  • AI document summarization - Feed extracted PDF text into an LLM prompt to summarize uploaded reports, contracts, or research papers.
  • Serverless PDF processing on the edge - Extract text or metadata from user-uploaded PDFs inside a Cloudflare Worker or other edge function with no Node-specific APIs required.
  • Search indexing - Extract and normalize text from a corpus of PDFs to build a full-text search index.
  • PDF link auditing - Extract all hyperlinks from a document to check for broken or outdated URLs before publishing.
  • Thumbnail generation - Render the first page of an uploaded PDF as an image to show a preview in a document library UI.

Under The Hood

Architecture The entry point (src/index.ts) wraps a handful of low-level modules (text.ts, image.ts, links.ts, meta.ts) with a call to resolvePDFJSImport() before each operation, ensuring the PDF.js module is lazily resolved once via a module-level singleton before any extraction runs. utils.ts centralizes document lifecycle in withDocument(): it accepts either raw binary data or an existing PDFDocumentProxy, creates one via getDocumentProxy if needed, runs the caller’s operation, and destroys the proxy only if it created it itself, avoiding accidental double-frees on caller-supplied documents. The serverless PDF.js bundle lives under src/pdfjs-serverless/ (mocks, polyfills, Rolldown config) and is built separately via a dedicated build:pdfjs script before the main build runs, then copied into the published dist/pdfjs.mjs — so the package ships two build artifacts from one source tree: the wrapped API and the inlined PDF.js bundle. Browser-only globals are stubbed defensively before every module resolution, and DOMMatrix is polyfilled for canvas-less environments. It’s a clean, single-purpose module layout — no framework, no DI container, just pure async functions layered over one shared resolution/lifecycle utility, so a change to that utility’s caching or reload semantics affects every extraction path at once.

Tech Stack Written almost entirely in TypeScript (85% by bytes) with a small JavaScript serverless bundle, targeting any modern JS engine (Node >=22, browsers, Deno, Bun, Cloudflare Workers). It has zero declared runtime dependencies — PDF.js is bundled at build time via Rolldown rather than pulled in as a package dependency; pdfjs-dist and @napi-rs/canvas are devDependency/optional-peerDependency only, used for the official-build escape hatch and canvas-based page rendering respectively. Build tooling is tsdown (dual ESM/CJS output plus a small post-build script) and Rolldown (for the standalone serverless PDF.js bundle), with TypeScript in a fairly strict configuration (noUncheckedIndexedAccess, verbatimModuleSyntax). Package management is pnpm workspaces around a single package.

Code Quality Tests run under Vitest and are split by concern — document handling, text extraction, image extraction, link extraction, metadata, and the raw PDF.js resolution path — with fixtures and snapshot coverage. The test setup file is a notable quality signal: it spies on console.warn across every test and fails if PDF.js logs an “is not a function/defined/constructor” warning, an explicit guard against the serverless bundle silently missing an API the official build has. Error handling is explicit rather than swallowed — failed module resolution is wrapped in descriptive errors naming what failed, instead of passing through raw PDF.js exceptions. Public APIs use function overloads so return types track option values (e.g. extractText’s string vs string[] result based on mergePages) rather than forcing callers to type-guard. CI runs the full build pipeline, an “Are The Types Wrong” packaging check, type-checking of both source and built declaration files, ESLint, and the test suite on every push and pull request.

API Design The library’s core idea is repackaging PDF.js — a browser-oriented, worker-dependent rendering engine — into something that runs unmodified in environments that can’t spawn workers or don’t have a DOM, by inlining the worker into one bundle and polyfilling the handful of APIs those environments lack. That’s a genuinely useful packaging solution to a real, recurring pain point (running PDF.js on Cloudflare Workers and similar edge runtimes) rather than a new algorithm. API ergonomics are strong: six focused async functions, sensible Node-specific defaults baked into getDocumentProxy (font and CMap resolution), a clean escape hatch to the raw PDF.js API or an alternate build, and overloaded return types that remove the need for manual type narrowing. Documentation pairs every exported function with a runnable example.

Used by 9 apps in this directory

TypeScript
99%
Other

Activepieces

Automation · AI Assistants

24,298

Open-source AI automation platform that converts 280+ workflow integrations into MCP servers for LLMs, with no-code builders and TypeScript extensibility.

View details
92
Repo Health
85
Technical
64
Dependency
Built with
TypeScript99%
Updated today
TypeScript
99%
Other

byterover-cli

AI Agents · AI Code Assistants

4,956

A portable memory layer for AI coding agents — curate structured project knowledge into a version-controlled context tree that syncs across tools, machines, and teammates.

View details
52
Repo Health
83
Technical
70
Dependency
Built with
TypeScript99%
Updated 2 months ago
TypeScript
95%
Other

LLM Gateway

AI Development · Devops

1,611

One API endpoint for 25+ LLM providers — route, track costs, enforce compliance, and switch models without changing your code.

View details
85
Repo Health
80
Technical
71
Dependency
Built with
TypeScript95%
Updated yesterday
TypeScript
96%
AGPL 3.0

Midday

Invoicing Finance · Productivity

14,958

All-in-one AI-powered business operations platform for freelancers and solo entrepreneurs to manage invoicing, time tracking, banking, and financial intelligence.

View details
55
Repo Health
78
Technical
70
Dependency
Built with
TypeScript96%
Updated 2 months ago
TypeScript
96%
Apache 2.0

Next AI Draw.io

Developer Tools · AI Design Tools · Design Tools

35,652

Turn natural language into professional draw.io diagrams with AI, cloud icons, and an MCP server for your IDE.

View details
83
Repo Health
80
Technical
72
Dependency
Built with
TypeScript96%
Updated yesterday
TypeScript
64%
Other

NocoDB

No Code Platforms · Databases · Low Code Platforms

64,861

Turn any SQL database into a collaborative no-code spreadsheet with automatic REST APIs and real-time views.

View details
90
Repo Health
77
Technical
62
Dependency
Built with
TypeScript64%
Vue31%
Updated 2 days ago
TypeScript
94%
AGPL 3.0

Papra

Bookmarks Archiving

5,296

Self-hosted document archiving with email ingestion, OCR full-text search, and pluggable storage — store once, find anything.

View details
86
Repo Health
82
Technical
69
Dependency
Built with
TypeScript94%
Updated yesterday
TypeScript
54%
MIT

Superagent

Security · AI Agents

6,731

An open-source SDK that blocks prompt injections, redacts PII and secrets, scans repositories for AI-targeted attacks, and red-teams production agents.

View details
71
Repo Health
66
Technical
77
Dependency
Built with
TypeScript54%
Python43%
Updated 1 weeks ago
TypeScript
72%
Apache 2.0

Valmis

AI Agents

107

A security-focused, self-hostable AI agent platform for production work — agents run in isolated containers that access credentials only through a host-side proxy, so the AI itself never sees API keys or plaintext credentials.

View details
74
Repo Health
69
Technical
75
Dependency
Built with
TypeScript72%
Svelte27%
Updated 6 days ago

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