All guides
GlassCompressWeb

How I Built GlassCompress

After GlassPad, I kept hearing the same request: “Can you shrink this photo before I email it?” Most online compressors want an upload. Many strip EXIF in ways you cannot see. Passport and social sizes are buried behind paywalls. GlassCompress is my answer — a free tool at glasscompress.madushka.com that runs entirely in your browser. Nothing leaves your device.

The problem

Travel clients send me huge JPEGs from phones. Job applications need passport-size crops. Social posts want exact aspect ratios. Desktop tools work, but not everyone has one installed — and uploading personal photos to a random website feels wrong.

  • No server upload — decode and encode in-memory only
  • Live output size while you drag quality or crop
  • Presets for passport, Instagram, Facebook, YouTube, OG images, and common ratios
  • HEIC/HEIF decode so phone photos work without a desktop converter
  • Flip/mirror, Help modal, GlassPad handoff, and installable PWA
  • Batch ZIP and image→PDF for paperwork

Stack and architecture

Follows the same lightweight philosophy as GlassPad — kept simple, with no unnecessary complexity. Integrated into the madushka.com ecosystem via its own clean subdomain (glasscompress.madushka.com), with the legacy tool path redirecting there.

Heavy compression work runs off the main thread so the interface stays responsive while processing. Handles the full range of common image formats, including HEIC. The main script manages the UI, live re-compression, crop/flip, Help, and downloads.

Pipeline: decode → crop → resize → encode

Each dropped file becomes an in-memory item: original dimensions, blob URL for preview, optional per-item rotation and crop rectangle. On every settings change, the pipeline:

  1. Draws the source image to a canvas (EXIF orientation handled at decode)
  2. Applies the crop region in pixel space
  3. Resizes to preset output or max-edge cap
  4. Encodes with quality slider or binary-searches toward a target KB
Preview gotcha

Revoking blob URLs too early blanked the preview on first ship. Keep object URLs alive until the item is removed — a small lifecycle detail that matters a lot in UX.

Crop UX (v1 → v2)

Early feedback: the crop frame felt “stuck” — users could drag but had no obvious save path and on mobile the stage sat below the fold. Fixes shipped in layers:

  • Toolbar with Reset frame and Download selection under the crop stage
  • Compact hero when images are loaded; scroll crop into view on mobile
  • Use full image one-click, arrow-key nudge, pinch-to-zoom, double-tap to reset zoom

Presets lock aspect ratio (passport mm/cm with DPI, 1080×1350 posts, story, covers). Free mode keeps all handles. The crop math lives in one module; the overlay is pure DOM + pointer events.

Presets and batch

Presets are data, not hard-coded UI branches — passport sizes, social templates, and ratio locks (1:1, 4:5, 16:9). Batch mode reuses the same settings per item, caps at 20 images, and zips with JSZip. PDF export uses pdf-lib for A4 sheets when clients need print-ready pages.

Privacy as architecture

No analytics on file contents. No upload endpoint. The Worker only serves static files and SEO feeds — the compression never hits my server.

Branding and discovery

GlassCompress follows the GlassPad pattern: product subdomain, glass UI, shared madushka.com footer links, tools hub card, command palette entry, case study at /projects/glasscompress/, and its own robots.txt + sitemap.xml on the subdomain for Search Console.

What I'd do differently

  • Ship crop toolbar in v1 — users need an obvious “done” affordance
  • Treat HEIC as day-one scope — most phone photos arrive as HEIC, not JPEG
  • Automated visual tests for crop overlay on narrow viewports
  • Document GlassPad ↔ GlassCompress handoff in the first Help pass, not as a later footnote

If you build your own

  1. Keep files on-device and say so loudly.
  2. Show output bytes before download — trust beats mystery.
  3. Invest in crop on mobile; compression is the easy part.
  4. Use a Worker for routing and SEO, not for user images.

That is the GlassCompress playbook: constrain the stack, decode HEIC early, encode in a worker, polish crop and flip, hand off to GlassPad when needed, never upload the photo.

Try it at glasscompress.madushka.com — or read How I Built GlassPad for the sibling story.