npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pdf-to-tiff-pure-aloka

v1.0.12

Published

Pure Node.js PDF to TIFF converter — no system dependencies, no native bindings. Uses pdfjs-dist + pureimage + utif.

Readme

pdf-to-tiff-pure-aloka

Pure Node.js PDF to TIFF converter — zero system dependencies, zero native bindings.
Uses pdfjs-dist (Mozilla) + pureimage + custom TIFF encoder. Works on any OS without installing Ghostscript, Poppler, or ImageMagick.

npm version license node


Table of Contents


Features

  • 100% pure JavaScript / TypeScript — no C++ bindings, no native add-ons
  • No system dependencies — no Ghostscript, Poppler, or ImageMagick required
  • Three compression modes — LZW, PackBits, or uncompressed
  • Barcode-safe binarization — Otsu adaptive threshold → crisp 1-bit black-and-white output
  • TypeScript types included — full .d.ts declarations shipped
  • One TIFF per PDF pagepage-1.tiff, page-2.tiff, …
  • PDF text extraction — extract all text from a PDF as a plain string
  • MIT License — free for commercial and open-source use

Requirements

| Requirement | Version | |-------------|---------| | Node.js | ≥ 18.0.0 | | npm | ≥ 8.0.0 |

No system libraries needed.


Installation

npm install pdf-to-tiff-pure-aloka

Quick Start

const { convertPdfToTiff, convertPdfToText } = require('pdf-to-tiff-pure-aloka');

async function main() {
  // Convert to TIFF
  const result = await convertPdfToTiff('document.pdf', './output');

  if (result.success) {
    console.log(`Converted ${result.convertedPages} pages:`);
    result.outputFiles.forEach(f => console.log(' -', f));
  } else {
    console.error('Conversion failed:', result.error);
  }

  // Extract text
  const text = await convertPdfToText('document.pdf');
  console.log(text);
}

main();

TypeScript:

import { convertPdfToTiff, convertPdfToText, ConversionOptions } from 'pdf-to-tiff-pure-aloka';

const options: ConversionOptions = {
  scale: 2.0,
  compression: 'lzw',
  filePrefix: 'scan',
};

const result = await convertPdfToTiff('document.pdf', './output', options);
console.log(result.outputFiles);
// Multi-page: → ['./output/scan-1.tiff', './output/scan-2.tiff', ...]
// Single-page: → ['./output/scan.tiff']

API Reference

convertPdfToTiff()

convertPdfToTiff(
  pdfPath: string,
  outputDir: string,
  options?: ConversionOptions
): Promise<ConversionResult>

Converts every page of a PDF file into individual TIFF files.

| Parameter | Type | Required | Description | |------------|---------------------|----------|-------------| | pdfPath | string | ✅ Yes | Path to the source PDF file (absolute or relative) | | outputDir| string | ✅ Yes | Directory where TIFF files are written. Created automatically if it does not exist. | | options | ConversionOptions | No | Optional settings (see below) |

Throws Error if:

  • The PDF file does not exist or cannot be read
  • The PDF is corrupt or has no pages
  • scale is outside the valid range (0 < scale ≤ 10)
  • The output directory cannot be created

convertPdfToTiffHighFidelity()

convertPdfToTiffHighFidelity(
  pdfPath: string,
  outputDir: string,
  options?: ConversionOptions
): Promise<ConversionResult>

Converts every page of a PDF file into individual TIFF files using node-canvas (Cairo rendering backend) for high-fidelity output.

Unlike the standard convertPdfToTiff() which uses pureimage, this function leverages the Cairo graphics library via node-canvas to achieve full Canvas 2D API support. This ensures embedded images, barcodes, QR codes, and complex vector graphics are rendered accurately in the output TIFF.

Use this when:

  • Your PDFs contain embedded images that must be preserved
  • Barcodes and QR codes need pixel-perfect fidelity
  • Complex vector graphics or gradients need accurate rendering
  • You need better font rendering for international text

Note: This function requires node-canvas to be installed. It may have system dependencies depending on your operating system (Cairo, pixman).

| Parameter | Type | Required | Description | |------------|---------------------|----------|-------------| | pdfPath | string | ✅ Yes | Path to the source PDF file (absolute or relative) | | outputDir| string | ✅ Yes | Directory where TIFF files are written. Created automatically if it does not exist. | | options | ConversionOptions | No | Optional settings (see below) |

Throws Error if:

  • node-canvas is not installed
  • The PDF file does not exist or cannot be read
  • The PDF is corrupt or has no pages
  • scale is outside the valid range (0 < scale ≤ 10)
  • The output directory cannot be created

ConversionOptions

interface ConversionOptions {
  scale?: number;             // Default: 3.0
  compression?: TiffCompression; // Default: 'lzw'
  filePrefix?: string;        // Default: 'page'
  binarize?: boolean;         // Default: false
}

type TiffCompression = 'none' | 'packbits' | 'lzw';

| Option | Type | Default | Description | |---------------|-------------------|------------|-------------| | scale | number | 3.0 | Render scale multiplier. 1.0 = 72 DPI (PDF native), 2.0 = 144 DPI, 3.0 ≈ 216 DPI (default), 4.17 ≈ 300 DPI. Valid range: (0, 10]. | | compression | TiffCompression | 'lzw' | TIFF compression algorithm. See Compression Modes. | | filePrefix | string | 'page' | Output filename prefix. Single-page PDFs: files are named ${prefix}.tiff (no page number). Multi-page PDFs: files are named ${prefix}-${pageNumber}.tiff. | | binarize | boolean | false | When true, converts each page to 1-bit black-and-white using Otsu's adaptive threshold before encoding. Eliminates the anti-aliased gray fringe that pureimage adds to barcode edges, making barcodes scannable by hardware readers and fax systems. Output IFD: BitsPerSample=1, PhotometricInterpretation=0 (WhiteIsZero). |


ConversionResult

interface ConversionResult {
  success: boolean;       // true if ALL pages converted successfully
  totalPages: number;     // total pages in the PDF
  convertedPages: number; // pages that were successfully written
  outputFiles: string[];  // absolute paths to each TIFF file, in page order
  error?: string;         // set if success is false
}

Examples

Convert with custom DPI (~300 DPI)

const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');

const result = await convertPdfToTiff('invoice.pdf', './tiff-output', {
  scale: 4.17,        // 4.17 × 72 DPI ≈ 300 DPI
  compression: 'lzw',
  filePrefix: 'invoice',
});
// Multi-page: → invoice-1.tiff, invoice-2.tiff, ...
// Single-page: → invoice.tiff

Output to current directory

const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');

const result = await convertPdfToTiff('document.pdf', './', {
  filePrefix: 'scan',
});

console.log(result.outputFiles);
// Single-page: → ['scan.tiff']
// Multi-page:  → ['scan-1.tiff', 'scan-2.tiff', ...]

Uncompressed output (fastest, largest files)

const result = await convertPdfToTiff('scan.pdf', './raw', {
  compression: 'none',
});

PackBits compression (fast, moderate size)

const result = await convertPdfToTiff('report.pdf', './compressed', {
  compression: 'packbits',
});

High-fidelity conversion with embedded images (node-canvas)

Use convertPdfToTiffHighFidelity() when your PDFs contain embedded images, complex graphics, or need pixel-perfect rendering:

const { convertPdfToTiffHighFidelity } = require('pdf-to-tiff-pure-aloka');

const result = await convertPdfToTiffHighFidelity('document-with-images.pdf', './output', {
  scale: 3.0,
  compression: 'lzw',
  filePrefix: 'page',
});

TypeScript:

import { convertPdfToTiffHighFidelity } from 'pdf-to-tiff-pure-aloka';

const result = await convertPdfToTiffHighFidelity('catalog.pdf', './output', {
  scale: 4.17,  // ~300 DPI for high quality
  compression: 'lzw',
});

Barcode / fax-quality output (1-bit black-and-white)

Use binarize: true when the PDF contains barcodes, QR codes, or must be sent to a fax system. The canvas renderer anti-aliases barcode edges, producing gray pixels that can confuse fixed-threshold hardware readers. Enabling binarization applies Otsu's adaptive threshold to remove all gray, writing a compact 1-bit TIFF instead of an 8-bit RGB one.

const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');

const result = await convertPdfToTiff('barcode-invoice.pdf', './output', {
  scale: 3.0,          // higher scale = more barcode detail
  compression: 'lzw',
  binarize: true,      // → 1-bit B&W TIFF, Otsu adaptive threshold
});

TypeScript:

import { convertPdfToTiff, ConversionOptions } from 'pdf-to-tiff-pure-aloka';

const options: ConversionOptions = {
  scale: 3.0,
  compression: 'lzw',
  binarize: true,
};

const result = await convertPdfToTiff('barcode.pdf', './output', options);
// Output TIFF: BitsPerSample=1, PhotometricInterpretation=0 (WhiteIsZero)

Tip: For documents that mix barcodes with full-colour content (logos, photos), leave binarize: false (default) and use a separate post-processing step for the pages that need scanning.

Error handling

const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');

try {
  const result = await convertPdfToTiff('document.pdf', './output');

  if (!result.success) {
    // Some pages failed (non-fatal per-page errors)
    console.warn(`Warning: ${result.error}`);
    console.log(`Converted ${result.convertedPages}/${result.totalPages} pages`);
  }

  result.outputFiles.forEach(file => {
    console.log('Created:', file);
  });

} catch (err) {
  // Fatal error: file not found, corrupt PDF, invalid options
  console.error('Fatal error:', err.message);
}

Check output file sizes

const fs = require('fs');
const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');

const result = await convertPdfToTiff('document.pdf', './output', {
  compression: 'lzw',
});

result.outputFiles.forEach(file => {
  const size = fs.statSync(file).size;
  console.log(`${file} — ${(size / 1024).toFixed(1)} KB`);
});

Extract text from a PDF

const { convertPdfToText } = require('pdf-to-tiff-pure-aloka');

const text = await convertPdfToText('document.pdf');
console.log(text);
// Output: full text of all pages, pages separated by \n\n

TypeScript:

import { convertPdfToText } from 'pdf-to-tiff-pure-aloka';

const text: string = await convertPdfToText('invoice.pdf');
if (text.trim().length > 0) {
  console.log('Extracted text:', text);
} else {
  console.log('No text found (image-only or encrypted PDF)');
}

Compression Modes

| Mode | TIFF Tag | File Size | Encoding Speed | Best For | |------------|----------|---------------|----------------|----------| | none | 1 | Largest | Fastest | Debugging, further processing | | packbits | 32773 | Moderate | Fast | General purpose | | lzw | 5 | Smallest | Moderate | Storage, archival (default) |

Tip: For text-heavy or white-space-heavy documents, LZW achieves the best compression ratio. For photos or complex vector art, the difference between modes is smaller.


convertPdfToText()

convertPdfToText(pdfPath: string): Promise<string>

Extracts all text content from a PDF file and returns it as a plain string.

| Parameter | Type | Required | Description | |-----------|----------|----------|-------------| | pdfPath | string | ✅ Yes | Path to the source PDF file (absolute or relative) |

Returns a Promise<string> — concatenated text of all pages, with pages separated by \n\n.

Returns an empty string if the PDF contains no extractable text (image-only or rasterized content).

Throws Error if:

  • The PDF file does not exist or cannot be read
  • The PDF is corrupt or has no pages

Note: Text extraction works on PDFs with embedded text streams. Scanned PDFs (images only) will return an empty string — use convertPdfToTiff to get image output and apply OCR separately if needed.


Known Limitations

| Limitation | Details | |------------|---------| | Performance | Rendering is 3–10× slower than system-library solutions (Ghostscript, Poppler) because everything runs in JavaScript. Expect ~1–5 seconds per page depending on complexity. | | Font rendering | PDFs that use unembedded proprietary fonts (e.g. old Vietnamese TCVN3 fonts) may render as empty boxes. Standard fonts (Helvetica, Times, Courier) require the standardFontDataUrl option of pdfjs-dist; this package uses best-effort fallback only. | | Color accuracy | Complex color spaces (CMYK, ICC profiles) are handled by pdfjs on a best-effort basis. Slight color shifts are possible. | | Memory usage | Very high-resolution renders (scale > 4.0) of large pages can use significant RAM. Process pages sequentially for large documents. | | No multi-page TIFF | Each page produces a separate .tiff file. Multi-page (strips) TIFF is not supported. || Binarize on mixed pages | binarize: true applies a single global Otsu threshold to the whole page. Pages with both full-colour photos and barcodes may lose colour detail. Use binarize: false (default) for colour output. |

License

MIT © pdf-to-tiff-pure-aloka contributors