Package Exports
- pdfpressor-client
Readme
pdfpressor-client
A standalone client-side PDF compressor. It loads a PDF in the browser, rasterizes each page to a canvas at a chosen DPI, recompresses pages as JPEG with configurable quality, and rebuilds a new PDF. Returns multiple handy artifacts (Uint8Array bytes, Blob, object URL, Buffer if available) plus detailed statistics.
Features
- Pure browser operation (no server round-trip required)
- Adjustable DPI (affects rendered page resolution)
- Adjustable JPEG quality (0.1–1.0 floating value)
- Optional detailed logging (opt-in)
- Side‑by‑side preview (original vs compressed first page)
- Download links for original and compressed output
- Simple API for React / vanilla JS
Installation (for bundlers / React)
npm install pdfpressor-client🎯 Zero Setup Required!
This package is 100% self-contained with all dependencies bundled directly. No configuration, no file copying, no CDN fallbacks needed.
Just install and use:
import { compressPdfClient } from 'pdfpressor-client';
const { compressFile } = await compressPdfClient(pdfBytes, 'output.pdf');What's included:
- ✅
pdf-lib.min.js(525 KB) - bundled - ✅
pdf.min.js(353 KB) - bundled - ✅
pdf.worker.min.js(1.38 MB) - bundled
All dependencies load automatically from the package. Works offline, no external requests.
Direct Browser Usage (CDN fallback)
You can copy the contents of this folder and serve it; dependencies are loaded from CDN automatically if module imports fail.
Serve locally (example):
npx http-server . -c-1
# then open http://localhost:8080/client-compressor/index.htmlHow It Works
This package is completely self-contained - all PDF libraries are bundled directly with the package.
Loading Strategy:
- Check if already loaded - Reuses existing window globals if present
- Load bundled files - Loads
pdf-lib.min.js,pdf.min.js, andpdf.worker.min.jsfrom the package - Ready to compress! - No external dependencies or network requests
Simple, reliable, and works everywhere (browser, offline, corporate firewalls, etc.)
Forcing / Overriding CDNs
Before calling compressPdfClient you may override URLs:
window.PDFPRESSOR_CLIENT_CDNS = {
pdfLib: [
'https://my.cdn.example/pdf-lib.min.js'
],
pdfjs: [
'https://my.cdn.example/pdf.min.js'
],
pdfjsWorker: [
'https://my.cdn.example/pdf.worker.min.js'
]
};Eager Initialization (Fail Fast)
You can preload and validate all dependencies early (e.g. on app startup) to avoid first‑interaction delays:
import { initPdfCompressor } from 'pdfpressor-client';
await initPdfCompressor({ logs: true, retries: 2 });If initialization fails it throws a PdfCompressorError with a .code value such as PDF_LIB_LOAD_FAILED, PDFJS_LOAD_FAILED, or INIT_FAILED.
Offline Usage
Because local minified copies are included, you can operate fully offline after the first install:
- Disconnect network
- Call
initPdfCompressor()(optional) thencompressPdfClient(...) - Loader will skip failed CDN attempts and transparently fall back to local scripts.
Environment Customization
- Set
logs=truewhen calling eitherinitPdfCompressororcompressPdfClientfor detailed timing and fallback logs. - Adjust retry attempts via
initPdfCompressor({ retries: 3 }).
API
compressPdfClient(
inputBytes: Uint8Array,
outputName: string,
dpi?: number, // default 150 (rendering DPI)
quality?: number, // default 0.7 (JPEG quality 0.1–1.0)
logs?: boolean // default false; enable console timing + diagnostic output
) => Promise<{ compressFile: {
bytes: Uint8Array;
blob: Blob;
objectUrl: string|null;
buffer: Buffer|null;
stats: {
outputName: string;
originalSize: number;
compressedSize: number;
reduction: number;
pageCount: number;
dpi: number;
quality: number;
};
}>>
initPdfCompressor(options?: {
logs?: boolean; // default false
retries?: number; // default 2 (script tag retry count per URL)
pdfLibUrls?: string[]; // override CDN list for pdf-lib
pdfjsUrls?: string[]; // override CDN list for pdfjs-dist main script
pdfjsWorkerUrls?: string[];// override CDN list for worker script
}): Promise<boolean>Parameters
inputBytes(Uint8Array): Raw PDF file bytes (e.g. fromfile.arrayBuffer())outputName(string): Suggested filename for downloaddpi(number, default 150): Render scale; higher DPI = larger images & potentially bigger outputquality(number, default 0.7): JPEG quality (0.1–1.0). Lower means smaller size (more compression)logs(boolean, default false): When true, enables detailed console.log, timing, and per‑page diagnostics
Returns
Single object { compressFile } where compressFile contains:
bytes: Compressed PDF as Uint8Arrayblob: Compressed PDF Blob for browser download / uploadobjectUrl: Created viaURL.createObjectURL(blob)for previewsbuffer: Node Buffer version (if Buffer exists)stats: Metadata for comparison & display
Example (React)
import { useState } from 'react';
import { compressPdfClient } from 'pdfpressor-client';
function PdfCompressor() {
const [stats, setStats] = useState(null);
const handleFile = async (e) => {
const file = e.target.files[0];
if (!file) return;
const bytes = new Uint8Array(await file.arrayBuffer());
// Enable logs for development
const { compressFile } = await compressPdfClient(bytes, 'compressed_' + file.name, 150, 0.7, true);
setStats(compressFile.stats);
const a = document.createElement('a');
a.href = compressFile.objectUrl;
a.download = compressFile.stats.outputName;
a.click();
};
return (
<div>
<input type="file" accept="application/pdf" onChange={handleFile} />
{stats && <pre>{JSON.stringify(stats, null, 2)}</pre>}
</div>
);
}Example (Vanilla JS)
const inputEl = document.querySelector('#pdfInput');
inputEl.onchange = async () => {
const file = inputEl.files[0];
if (!file) return;
const bytes = new Uint8Array(await file.arrayBuffer());
// logs disabled (false) for cleaner production console
const { compressFile } = await compressPdfClient(bytes, 'compressed_' + file.name, 144, 0.6, false);
console.log('Reduction %', compressFile.stats.reduction.toFixed(2));
const link = document.createElement('a');
link.href = compressFile.objectUrl;
link.download = compressFile.stats.outputName;
link.click();
};What It Accepts
- Input: Any standard PDF file (binary bytes as Uint8Array)
- Parameters:
outputName,dpi,quality,logs
What It Outputs
- Compressed PDF (rasterized pages) via
compressFile.bytes - Browser-friendly
BlobandobjectUrl - Statistics comparing original vs compressed sizes
Internals / How It Works
- Load PDF bytes (pdfjs-dist)
- Render each page to a canvas at
dpi/72scale - Export canvas as JPEG (
toDataURL('image/jpeg', quality)) and convert to bytes - Embed compressed images into a fresh PDF (pdf-lib)
- Produce output artifacts and stats
- If
logsis true, output timing for load, render, encode, embed, and final save
Limitations
- Text selectable content is lost (pages become images)
- Very large PDFs may cause memory spikes (each page rendered to canvas)
- JPEG only (no WebP/AVIF fallback due to pdf-lib restrictions)
- Compression dependent on browser's JPEG encoder
Tips
- Lower
dpi(e.g. 96) andquality(e.g. 0.5) for smaller outputs - Keep original PDF if you need selectable text
- Use web workers for large batch compression to keep UI responsive
- Enable
logsduring development, disable in production for minimal console noise - Call
initPdfCompressor()on startup to surface any blocked CDN issues early
Credits / Acknowledgements
- Inspired by Ralph Joseph Lagumen.
- Inspired by and gives credit to the original pdfpressor project (https://www.npmjs.com/package/pdfpressor) for conceptual guidance on PDF compression approaches.
License
MIT