<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gaurav Bhowmick</title>
    <description>The latest articles on DEV Community by Gaurav Bhowmick (@bhowmick773).</description>
    <link>https://dev.to/bhowmick773</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3887684%2Fb1e034c9-d9b6-466c-ba56-2a435f8e7961.png</url>
      <title>DEV Community: Gaurav Bhowmick</title>
      <link>https://dev.to/bhowmick773</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bhowmick773"/>
    <language>en</language>
    <item>
      <title>I built a free image compressor that never uploads your files</title>
      <dc:creator>Gaurav Bhowmick</dc:creator>
      <pubDate>Sun, 19 Apr 2026 18:13:12 +0000</pubDate>
      <link>https://dev.to/bhowmick773/i-built-a-free-image-compressor-that-never-uploads-your-files-1p1</link>
      <guid>https://dev.to/bhowmick773/i-built-a-free-image-compressor-that-never-uploads-your-files-1p1</guid>
      <description>&lt;p&gt;Every free image compressor I tried had the same problems: they upload your images to some server, limit you to 5 files a day, or force you to create an account.&lt;br&gt;
I just wanted to drop images, compress, download. So I built one.&lt;br&gt;
Meet MiniPx&lt;br&gt;
minipx.com — a free image compressor that runs 100% in your browser. Your images never leave your device.&lt;br&gt;
How it works&lt;br&gt;
The compression engine uses the HTML5 Canvas API. Here's the core idea:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Load the image into a Canvas element&lt;/li&gt;
&lt;li&gt;Re-encode it at a lower quality using canvas.toBlob()&lt;/li&gt;
&lt;li&gt;If the output is larger than the original (happens with PNGs), try progressively lower quality settings&lt;/li&gt;
&lt;li&gt;If WebP still can't beat the original, fall back to JPEG&lt;/li&gt;
&lt;li&gt;Always return the smallest successful result&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Code:&lt;br&gt;
// Simplified version of the multi-pass compression&lt;br&gt;
async function compress(file, quality, format) {&lt;br&gt;
  const img = await loadImage(file);&lt;br&gt;
  const canvas = document.createElement('canvas');&lt;br&gt;
  canvas.width = img.naturalWidth;&lt;br&gt;
  canvas.height = img.naturalHeight;&lt;br&gt;
  const ctx = canvas.getContext('2d');&lt;br&gt;
  ctx.drawImage(img, 0, 0);&lt;/p&gt;

&lt;p&gt;// First pass&lt;br&gt;
  let blob = await canvasToBlob(canvas, format, quality);&lt;/p&gt;

&lt;p&gt;// Smart fallback if output is larger&lt;br&gt;
  if (blob.size &amp;gt;= file.size) {&lt;br&gt;
    for (const q of [0.6, 0.45, 0.3, 0.2]) {&lt;br&gt;
      const attempt = await canvasToBlob(canvas, format, q);&lt;br&gt;
      if (attempt.size &amp;lt; file.size) {&lt;br&gt;
        blob = attempt;&lt;br&gt;
        break;&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
  return blob;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;The key insight: Canvas API quality values aren't linear. Quality 0.92 barely compresses anything. Quality 0.65 (our "Smart" preset) gives 50-70% reduction with no visible quality loss.&lt;br&gt;
Features&lt;/p&gt;

&lt;p&gt;Compress — Gentle (20-40%), Smart (50-70%), Tiny (75-90%)&lt;br&gt;
Convert — WebP, JPEG, PNG in any direction&lt;br&gt;
Resize — Set max width to 1920, 1280, or 800px&lt;br&gt;
Batch — No file limits, process as many as you want&lt;br&gt;
Private — Zero server uploads, works offline&lt;/p&gt;

&lt;p&gt;Tech stack&lt;/p&gt;

&lt;p&gt;Next.js 15 (static export)&lt;br&gt;
React 19&lt;br&gt;
Canvas API for compression&lt;br&gt;
Deployed on Netlify (zero server cost)&lt;/p&gt;

&lt;p&gt;What I learned&lt;br&gt;
Canvas API quality is not what you think. I initially set the "Smart" preset to quality 0.78 thinking that's decent compression. A 3MB PNG screenshot compressed to 3.2MB — larger than the original. Turns out 0.78 is barely any compression for the Canvas encoder. Dropping to 0.65 fixed everything.&lt;br&gt;
The multi-pass approach matters. A single-pass compressor will sometimes produce files larger than the original, especially with PNG screenshots. The fallback chain (try lower quality → try different format) ensures the output is always smaller.&lt;br&gt;
Static sites are underrated for tools. MiniPx costs $0/month to run. No server, no database, no file storage, no bandwidth costs. The entire thing is HTML/CSS/JS served from a CDN.&lt;br&gt;
Try it&lt;br&gt;
minipx.com — would love your feedback. What features would you want added?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>privacy</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
