Documentation
Installation
Install via npm, yarn, or pnpm:
npm install compresso.js
# or
yarn add compresso.js
# or
pnpm add compresso.jsOr 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
| Option | Type | Default | Description |
|---|---|---|---|
quality | number | 0.8 | Output quality, 0 to 1 |
maxWidth | number | Infinity | Maximum output width in pixels |
maxHeight | number | Infinity | Maximum output height in pixels |
format | string | 'auto' | 'jpeg' | 'png' | 'webp' | 'avif' | 'auto' |
maxSizeMB | number | Infinity | Maximum file size in MB |
backgroundColor | string | '#ffffff' | Background color for transparent → JPEG |
onProgress | function | — | Progress callback |
signal | AbortSignal | — | Cancel compression |
Result Object
| Property | Type | Description |
|---|---|---|
file | File | Optimized File object |
blob | Blob | Optimized Blob |
url | string | Object URL for preview |
width | number | Output width |
height | number | Output height |
originalSize | number | Original size in bytes |
compressedSize | number | Compressed size in bytes |
savings | number | Reduction percentage |
format | string | Output 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
| Browser | JPEG/PNG | WebP | AVIF |
|---|---|---|---|
| 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 processing | Client-side (Compresso) | |
|---|---|---|
| Infrastructure cost | Scales with traffic | Zero (user's device) |
| Processing latency | 200–2000ms per image | <100ms |
| Works offline | No | Yes |
| Image leaves device | Yes (uploaded raw) | Only optimized version |
| Server dependencies | Sharp, ImageMagick, etc. | None |