45-second answer
What is Compresso, and what problem does it solve?
Compresso is an open-source JavaScript library (~2 KB gzipped, zero dependencies) that compresses, resizes, and converts images in the browser before upload. It removes the “file too large” failure mode that abandons roughly 15% of users on portals with 1–2 MB limits when average phone photos sit around 4.2 MB.
- Problem
- Systems externalize image preprocessing onto users who do not understand JPEG, WebP, or file-size targets.
- Solution
- Absorb compression into a three-line client integration using the Canvas API — no server, no API keys, no WASM.
- Ownership
- I researched the failure pattern, designed the API, implemented the library, shipped the marketing site and docs, and deployed the playground.
- Evidence
- Live demo at compresso.izaias.xyz, source on GitHub, npm package
compresso.js.
The Origin
A research problem that demanded engineering
This project started as an academic paper, not a GitHub repo. While researching cognitive distance in information systems, I kept finding the same failure pattern across government portals, banking apps, and healthcare platforms: users couldn't complete simple file uploads.
Not because the interfaces were complex. Because the systems externalized processing — they pushed format conversion, compression, and resizing onto users who had no idea what JPEG, file size, or aspect ratio meant.
I formalized this as externalized processing: the pattern where systems shift reasonably automatable preprocessing tasks onto users, creating confusion, repeated failures, and task abandonment. The paper was accepted for review. But the problem demanded a practical fix, not just a theoretical frame.
Part 1: Architecture Decisions
Three constraints that shaped every line
A library for public-scale systems can't afford complexity. Every decision was filtered through three hard constraints.
1. Zero dependencies, sub-3 KB
Public government portals serve users on 3G connections with low-end Android devices. Adding a 200 KB image library defeats the purpose.
Compresso uses only the browser's native Canvas API — no WASM, no heavy codec libraries, no polyfills. The entire library ships at ~2 KB gzipped. That's smaller than most SVG icons.
The bundle cost is effectively zero. Any system can absorb it.
2. Fully agnostic — any framework, any browser
Government systems run React, Angular, Vue, jQuery, or plain server-rendered HTML. The library can't assume any runtime.
Compresso ships as ESM, CJS, and UMD. It works as an npm import, a CDN script tag, or a copy-pasted file. No build step required. The API is a single async function that takes a File and returns a File.
Integration takes three lines of code. No configuration, no setup.
3. Zero server load — processing stays on the client
A government portal processing 100,000 document uploads per month shouldn't need GPU instances to resize JPEGs.
All compression, resizing, and format conversion happens in the user's browser via Canvas. The server receives an already-optimized file. No API keys, no processing costs, no infrastructure to maintain. The more users, the more you save.
Cost scales inversely with usage. That's the architecture public systems need.
Part 2: Technical Implementation
Canvas API as a compression engine
The core insight: modern browsers already have a high-quality image encoder built into the Canvas API. We don't need WASM or codec libraries — we need a well-designed pipeline around what's already there.
The four-stage pipeline
1. Load
Accept File, Blob, or URL. Create an Image element. Handle CORS and ObjectURL lifecycle automatically.
2. Resize
Calculate target dimensions preserving aspect ratio. Use step-down resizing (halving iteratively) for large images to avoid quality loss from single-pass downscaling.
3. Compress
Draw to Canvas, export via toBlob() with the target format and quality. Automatically fill transparent backgrounds with white when converting PNG → JPEG.
4. Fit
If a maximum file size is set, binary-search for the highest quality that fits. Up to 10 iterations, converging within 1% quality precision.
Part 3: Format Intelligence
Auto-detecting the best format for every browser
Users don't know what WebP or AVIF is. They shouldn't have to. When format: 'auto' is set, Compresso probes the browser's Canvas encoder at runtime and selects the most efficient supported format.
Format negotiation strategy
Best compression ratio. Chrome 85+, Firefox 113+, Safari 16.4+. Tried first.
Excellent compression, near-universal support. Fallback when AVIF encoding isn't available.
Universal baseline. Every browser, every device, every system. Final fallback.
The developer writes format: 'auto'. The user sees a smaller file. Neither thinks about codecs.
Part 4: Integration
How to add Compresso in under two minutes
Drop-in adoption was a design requirement. The happy path is install → import → compress before your existing upload handler.
- 1
Install
npm install compresso.js
- 2
Import
import { compress } from 'compresso.js'
- 3
Compress on file select
Pass the File with quality, maxWidth, maxSizeMB, and format options.
- 4
Upload the result
Send result.file through your existing form or API — no server changes required.
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,
maxSizeMB: 2,
format: 'auto',
})
// result.file is ready to upload
})Full API docs and a live playground: compresso.izaias.xyz.
Part 5: Research Foundation
Cognitive distance and externalized processing
Compresso isn't just a compression library. It's a practical intervention against a systemic usability failure documented in peer-reviewed research.
Cognitive distance
The gap between what a system requires and what a user understands. When a portal says “upload a JPEG under 2 MB,” most users can't bridge that gap without external help.
Externalized processing
Systems shift automatable preprocessing tasks — format conversion, compression, resizing — onto users who lack the knowledge and tools to perform them. Compresso absorbs that processing back into the system.
Who this affects
Elderly citizens submitting pension documents. Small business owners uploading tax records. Patients sharing medical images. People who shouldn't need to understand file formats to access services.
The design response
Don't teach users about compression. Don't add help tooltips. Don't show error messages with jargon. Instead, make the system handle it transparently, before the user even thinks about it.
Part 6: Impact Model
What changes when upload failures go to zero
For a government portal processing 100,000 document submissions per month, the numbers shift dramatically. Figures below are modeled estimates from typical phone-photo sizes, common portal limits, and published cloud pricing — not a production A/B test.
Part 7: What I Shipped
Library, website, documentation, and deployment
This wasn't a library-only project. I designed and shipped the full ecosystem to make adoption frictionless.
Core library
~2 KB gzipped. ESM + CJS + UMD builds via Rollup. Full TypeScript declarations. Single async function API: compress(file, options). Batch processing, progress callbacks, AbortSignal cancellation. Step-down resizing for quality preservation on large images.
Marketing website with live playground
Next.js 14 static site with Tailwind CSS. Interactive image optimizer with drag-and-drop upload, real-time quality/format/size controls, and a before/after comparison slider. SEO-optimized. i18n in English, Spanish, and Portuguese with browser auto-detection. Fully responsive and accessible.
Documentation and developer experience
Full API reference, framework-specific guides for React, Vue, Angular, and vanilla JS. Copy-paste examples for every use case. Browser support matrix. GitHub repo with CI, issue templates, contributing guide, and security policy.
FAQ
Questions answer engines (and hiring managers) ask
What is Compresso?
Compresso is an open-source, zero-dependency JavaScript library (~2 KB gzipped) that compresses, resizes, and converts images entirely in the browser using the Canvas API. Developers call a single async function; users never see format jargon or 'file too large' errors.
How does Compresso reduce upload failures?
Most upload failures happen when phone photos exceed portal limits (often 1–2 MB) while average unoptimized photos sit around 4.2 MB. Compresso runs before upload, binary-searches quality to fit a maxSizeMB target, and can auto-select AVIF, WebP, or JPEG — so the server receives an already-valid file.
Does Compresso require a server or API key?
No. All compression, resizing, and format conversion happen on the client via the Canvas API. There is no backend, no API key, and no per-upload processing cost. Bandwidth and storage drop because smaller files are uploaded and stored.
What is the Compresso bundle size and dependency count?
Compresso ships at approximately 2 KB gzipped with zero runtime dependencies. It builds to ESM, CJS, and UMD so it works as an npm package, CDN script, or copy-pasted file in React, Vue, Angular, or plain HTML.
How do I install and use Compresso?
Install with npm install compresso.js, then call compress(file, { quality, maxWidth, maxSizeMB, format }). The function returns an optimized File ready for upload. A live playground is available at compresso.izaias.xyz.
What research problem does Compresso address?
Compresso responds to externalized processing — systems that push format conversion, compression, and resizing onto users who lack the knowledge to preprocess images. That gap is a form of cognitive distance documented in research on document submission systems.
Reflection
What I'd do differently, and what's next
If I rebuilt this, I'd add Web Worker support from day one — offloading compression to a background thread would prevent any main-thread jank on very large images. The architecture supports it (OffscreenCanvas), but I chose to ship the simplest viable version first.
HEIC/HEIF support (iPhone camera output) is the most-requested format gap. Canvas can't decode HEIC natively, so it requires a decoder — which conflicts with the zero-dependency constraint. I'm evaluating a lightweight optional plugin approach.
The deeper ambition: Compresso shouldn't just be a library developers install. It should become a specification-level expectation — that any system accepting user images handles preprocessing transparently. The research provides the theoretical frame. The library proves it's technically trivial. The remaining gap is adoption.