JSPM

  • Created
  • Published
  • Downloads 88
  • Score
    100M100P100Q66560F
  • License MIT

Client-side PDF compressor: rasterize pages and rebuild compressed PDF (pdf-lib + pdfjs-dist).

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

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.html

API

compressPdfClient(
  inputBytes: Uint8Array,
  outputName: string,
  dpi?: number,
  quality?: number,
  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;
  };
}>>

Parameters

  • inputBytes (Uint8Array): Raw PDF file bytes (e.g. from file.arrayBuffer())
  • outputName (string): Suggested filename for download
  • dpi (number, default 150): Render scale; higher DPI = larger images & potentially bigger output
  • quality (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 Uint8Array
  • blob: Compressed PDF Blob for browser download / upload
  • objectUrl: Created via URL.createObjectURL(blob) for previews
  • buffer: 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 Blob and objectUrl
  • Statistics comparing original vs compressed sizes

Internals / How It Works

  1. Load PDF bytes (pdfjs-dist)
  2. Render each page to a canvas at dpi/72 scale
  3. Export canvas as JPEG (toDataURL('image/jpeg', quality)) and convert to bytes
  4. Embed compressed images into a fresh PDF (pdf-lib)
  5. Produce output artifacts and stats
  6. If logs is 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) and quality (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 logs during development, disable in production for minimal console noise

Credits / Acknowledgements

License

MIT