Convert PDFs to images in Node.js and browsers
A modern, high-performance PDF to image converter powered by pdfjs-dist. Works seamlessly in both Node.js (18+) and modern browsers with a unified API.
| Feature | Description |
|---|---|
| π Dual Runtime | Works in Node.js 18+ and modern browsers |
| π Multiple Formats | Export to PNG, JPEG, or WebP |
| π― Page Ranges | Flexible page selection (1-3,5,9-) |
| πΌοΈ Thumbnails | Generate thumbnails in the same run |
| β‘ Concurrent Rendering | Configurable concurrency for performance |
| π Deterministic Output | Stable naming and sorted output |
| π§ CLI Included | Full-featured command-line interface |
| πͺ Post-Processing | Optional hooks for custom transforms |
npm install pdftoimg-jsNode.js rendering requires a canvas implementation. Install one of these:
# Recommended (faster, no native dependencies)
npm install @napi-rs/canvas
# Alternative
npm install canvasimport { convert, listPages } from "pdftoimg-js";
// List page metadata
const pages = await listPages("./document.pdf");
console.log(`Total pages: ${pages.length}`);
// Convert to images
const result = await convert("./document.pdf", {
format: "png",
pages: "1-3",
dpi: 200,
output: { outputDir: "./images" },
});
console.log(result.pages.map((p) => p.filePath));import { convert, listPages, setPdfWorkerSrc } from "pdftoimg-js/browser";
// Configure PDF.js worker (recommended for performance)
setPdfWorkerSrc(
new URL("pdfjs-dist/build/pdf.worker.mjs", import.meta.url).toString()
);
// Convert file input to images
const result = await convert(file, {
format: "png",
output: { outputType: "blob" },
});
// Display the first page
const url = URL.createObjectURL(result.pages[0].blob!);convert(input, options?): Promise<ConversionResult>
listPages(input, options?): Promise<PageInfo[]>interface ConversionResult {
pages: RenderedPage[];
thumbnails?: RenderedPage[];
totalPages: number;
timings: { load, parse, render, encode, save };
}
interface RenderedPage {
pageNumber: number;
width: number;
height: number;
rotation: number;
filePath?: string; // Node.js only
blob?: Blob; // Browser only
bytes?: Uint8Array; // When inMemory is true
}| Option | Type | Default | Description |
|---|---|---|---|
pages |
"all" | number[] | string |
"all" |
Page range (1-3,5,9-) |
format |
"png" | "jpeg" | "webp" |
"png" |
Output image format |
quality |
number |
0.92 |
JPEG/WebP quality (0-1) |
scale |
number |
1 |
Render scale (overrides dpi) |
dpi |
number |
72 |
Render DPI (72 = 1x) |
maxConcurrency |
number |
4 |
Max concurrent renders |
background |
string |
"transparent" |
Background color |
password |
string |
β | PDF password |
pageRotation |
number |
0 |
Additional rotation (degrees) |
naming |
NamingOptions |
{basename}-p{page}.{ext} |
Output naming pattern |
thumbnails |
ThumbnailOptions |
β | Generate thumbnails |
postProcess |
PostProcessHook |
β | Custom transform hook |
output: {
outputDir?: string; // Default: "output"
inMemory?: boolean; // Return bytes instead of writing files
}output: {
inMemory?: boolean; // Default: true
outputType?: "blob" | "bytes"; // Default: "blob"
}# Basic conversion
pdftoimg input.pdf --out ./images --format png
# With options
pdftoimg input.pdf --dpi 300 --pages 1-5 --format jpeg --quality 0.9
# List page metadata
pdftoimg input.pdf --list-pages --json
# Generate thumbnails
pdftoimg input.pdf --thumbs 0.25
# Output to zip
pdftoimg input.pdf --zip
pdftoimg input.pdf --stdout > output.zip| Option | Description |
|---|---|
--out <dir> |
Output directory (default: output) |
--format <fmt> |
png, jpeg, or webp |
--dpi <n> |
Render DPI (72 = 1x) |
--scale <n> |
Render scale (overrides dpi) |
--pages <range> |
Page range string |
--concurrency <n> |
Max concurrent renders |
--quality <n> |
JPEG/WebP quality (0-1) |
--background <color> |
Background color or transparent |
--password <pwd> |
PDF password |
--rotation <deg> |
Extra rotation in degrees |
--list-pages |
List page metadata only |
--zip |
Output as zip file |
--thumbs <scale> |
Generate thumbnails |
--stdout |
Write to stdout |
--quiet |
Suppress progress logs |
--json |
JSON output mode |
For backward compatibility with v0.x, the legacy pdfToImg and singlePdfToImg functions are still available. These return base64-encoded data URLs.
import { pdfToImg } from "pdftoimg-js";
const dataUrl = await pdfToImg("./document.pdf", {
pages: "firstPage",
imgType: "jpg",
scale: 2,
});import { pdfToImg } from "pdftoimg-js/browser";
const dataUrls = await pdfToImg(fileUrl, {
pages: { startPage: 1, endPage: 3 },
imgType: "png",
});| Option | Type | Default |
|---|---|---|
pages |
"firstPage" | "lastPage" | "all" | number | number[] | {startPage, endPage} |
"all" |
imgType |
"png" | "jpg" |
"png" |
scale |
number |
1 |
background |
string |
"rgb(255,255,255)" |
intent |
"display" | "print" | "any" |
"display" |
maxWidth |
number |
β |
maxHeight |
number |
β |
const result = await convert("./document.pdf", {
format: "jpeg",
quality: 0.85,
output: { inMemory: true },
});
// Access raw bytes
const bytes = result.pages[0].bytes;const result = await convert("./document.pdf", {
format: "png",
thumbnails: {
scale: 0.25,
format: "jpeg",
quality: 0.8,
},
});
console.log(result.thumbnails);const result = await convert("./document.pdf", {
naming: {
pattern: "page-{page}.{ext}",
zeroPad: 3,
},
});
// Output: page-001.png, page-002.png, ...const result = await convert("./document.pdf", {
postProcess: async (payload, context) => {
console.log(`Processed page ${context.pageNumber}`);
return payload; // Return modified payload if needed
},
});- Deterministic Output: Stable file naming with
{basename}-p{page}.{ext}pattern - Sorted Results: Pages are always returned in order regardless of concurrency
- Zip Consistency: Fixed file ordering and timestamps for reproducible archives
- Transparent Background: Default for PNG/WebP; JPEG falls back to white
MIT Β© Rashed Iqbal