Compresso

Documentation

Installation

Install via npm, yarn, or pnpm:

npm install compresso.js
# or
yarn add compresso.js
# or
pnpm add compresso.js

Or use directly from a CDN:

<script src="https://unpkg.com/compresso.js/dist/compresso.umd.js"></script>

Quick Start

import { compress } from 'compresso.js';

const input = document.querySelector('input[type="file"]');

input.addEventListener('change', async (e) => {
  const file = e.target.files[0];

  const result = await compress(file, {
    quality: 0.8,
    maxWidth: 1920,
    format: 'webp',
  });

  console.log(`${result.savings}% smaller`);
  // result.file → optimized File, ready for upload
  // result.url  → object URL for preview
});

API Reference

compress(source, options?)

Compresses a single image. Accepts a File, Blob, or image URL string.

compressMultiple(files, options?)

Compresses an array of files sequentially.

createCompressor(defaults?)

Creates a reusable compressor instance with preset options:

const optimizer = createCompressor({
  quality: 0.7,
  maxWidth: 1200,
  format: 'webp',
});

const result = await optimizer.compress(file);

Options

OptionTypeDefaultDescription
qualitynumber0.8Output quality, 0 to 1
maxWidthnumberInfinityMaximum output width in pixels
maxHeightnumberInfinityMaximum output height in pixels
formatstring'auto''jpeg' | 'png' | 'webp' | 'avif' | 'auto'
maxSizeMBnumberInfinityMaximum file size in MB
backgroundColorstring'#ffffff'Background color for transparent → JPEG
onProgressfunctionProgress callback
signalAbortSignalCancel compression

Result Object

PropertyTypeDescription
fileFileOptimized File object
blobBlobOptimized Blob
urlstringObject URL for preview
widthnumberOutput width
heightnumberOutput height
originalSizenumberOriginal size in bytes
compressedSizenumberCompressed size in bytes
savingsnumberReduction percentage
formatstringOutput format

Target File Size

Set maxSizeMB to ensure the output never exceeds a given file size. Compresso uses binary search to find the highest quality that fits:

const result = await compress(file, {
  maxSizeMB: 2,    // Output will be ≤ 2 MB
  format: 'jpeg',
});

Progress Tracking

const result = await compress(file, {
  onProgress: ({ progress, stage }) => {
    console.log(`${stage}: ${Math.round(progress * 100)}%`);
    // loading: 10% → resizing: 30% → compressing: 50-90% → done: 100%
  },
});

Cancellation

const controller = new AbortController();

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

try {
  const result = await compress(file, {
    signal: controller.signal,
  });
} catch (err) {
  if (err.name === 'AbortError') {
    console.log('Compression was cancelled');
  }
}

Format Detection

import { isFormatSupported, getBestFormat, detectFormat } from 'compresso.js';

// Check if the current browser supports AVIF
isFormatSupported('avif');  // true or false

// Get the best format the browser supports
getBestFormat();  // 'avif', 'webp', or 'jpeg'

// Detect format from a file
detectFormat(file);  // 'png', 'jpeg', etc.

Framework Guides

React

import { useState } from 'react';
import { compress, formatBytes } from 'compresso.js';

function ImageUpload() {
  const [result, setResult] = useState(null);

  async function handleFile(e) {
    const file = e.target.files[0];
    if (!file) return;
    setResult(await compress(file, { quality: 0.8, format: 'webp' }));
  }

  return (
    <div>
      <input type="file" accept="image/*" onChange={handleFile} />
      {result && (
        <p>{formatBytes(result.originalSize)} → {formatBytes(result.compressedSize)} ({result.savings}% smaller)</p>
      )}
    </div>
  );
}

Vue

<script setup>
import { ref } from 'vue';
import { compress } from 'compresso.js';

const result = ref(null);

async function handleFile(e) {
  const file = e.target.files[0];
  if (!file) return;
  result.value = await compress(file, { quality: 0.8, format: 'webp' });
}
</script>

<template>
  <input type="file" accept="image/*" @change="handleFile" />
  <p v-if="result">{{ result.savings }}% smaller</p>
</template>

Vanilla JS (CDN)

<script src="https://unpkg.com/compresso.js/dist/compresso.umd.js"></script>
<script>
  document.getElementById('upload').addEventListener('change', async (e) => {
    const result = await Compresso.compress(e.target.files[0], {
      quality: 0.8,
      format: 'webp',
      maxSizeMB: 2,
    });
    console.log(result.savings + '% smaller');
  });
</script>

Browser Support

BrowserJPEG/PNGWebPAVIF
Chrome 32+✓ (85+)
Firefox 29+✓ (96+)✓ (113+)
Safari 8+✓ (16+)✓ (16.4+)
Edge 79+✓ (121+)

When using format: 'auto', Compresso automatically detects the best format supported by the current browser.

Why optimize in the browser?

Client-side optimization means the server receives an already-optimized file. No server-side processing, no GPU instances, no image processing libraries to maintain. The heavier the traffic, the more you save — because each user's device does the work.

Server-side processingClient-side (Compresso)
Infrastructure costScales with trafficZero (user's device)
Processing latency200–2000ms per image<100ms
Works offlineNoYes
Image leaves deviceYes (uploaded raw)Only optimized version
Server dependenciesSharp, ImageMagick, etc.None