Open Source Library · Highlight #02 · 2026

Open SourceLive Demonpm: compresso.js

2 KB that eliminates 'file too large' for millions of users

A zero-dependency JavaScript library that compresses, resizes, and converts images entirely in the browser — grounded in cognitive distance research on why users fail simple file uploads.

Role

Design EngineerResearch → architecture → ship

Scope

End-to-endLibrary + website + docs + deploy

Stack

Vanilla JS · Canvas APIZero dependencies

Target

Public SystemsGov portals, healthcare, finance

  • ~2 KB

    Gzipped Bundle

    Smaller than most favicons

  • ~90%

    Avg. Size Reduction

    4.2 MB → ~0.4 MB typical

  • 0

    Dependencies

    Pure browser APIs

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

AVIF

Best compression ratio. Chrome 85+, Firefox 113+, Safari 16.4+. Tried first.

WebP

Excellent compression, near-universal support. Fallback when AVIF encoding isn't available.

JPEG

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

    Install

    npm install compresso.js

  2. 2

    Import

    import { compress } from 'compresso.js'

  3. 3

    Compress on file select

    Pass the File with quality, maxWidth, maxSizeMB, and format options.

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

Without
With Compresso
Avg. file size
4.2 MB
0.4 MB
Monthly bandwidth
420 GB
40 GB
Upload failures
~15%
~0%
Server processing
Heavy
None
User confusion
High
None

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.