{
  "id": 7922387,
  "title": "Writing a real PNG compressor in vanilla JavaScript (no WASM, no libraries)",
  "url": "https://urgent.news/2026/09/17/writing-a-real-png-compressor-in-vanilla-javascript-no-wasm-no",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-17T01:46:09.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/ihtisham130/writing-a-real-png-compressor-in-vanilla-javascript-no-wasm-no-libraries-2amn"
  },
  "original_language": "en",
  "account": "Every online image converter requires users to upload files to a server before providing a download link. This approach works for simple tasks like sharing memes but fails when dealing with sensitive documents, such as passport scans. It is the most common type of file conversion people perform. To explore how far a browser can go without relying on external servers, the author decided to create a real PNG compressor using vanilla JavaScript—without WebAssembly (WASM) or libraries.\n\nBrowsers can decode and encode various image formats, including PNG, JPEG, WebP, GIF, BMP, AVIF, SVG, and ICO. However, the only three formats they can encode are PNG, JPEG, and WebP. If you need to create or manipulate other formats like BMP or ICO, you must write the code to handle them byte by byte.\n\nThe first trap the author encountered was with the `canvas.toBlob()` method. This method accepts a MIME type as an argument, and when given an unsupported format, it doesn't throw an error or return null. Instead, it silently generates a PNG with a successful callback. For instance, creating a PNG from an AVIF image using `canvas.toBlob()` would result in a file named `.avif`, which is actually a PNG. This deceptive behavior can lead users to believe their conversions are working correctly, but the files are actually in the wrong format. To avoid this issue, the author recommends checking the MIME type returned by `toBlob()` against the one requested.\n\nThe second trap involves the compression of PNG images. When converting a PNG to a blob using `canvas.toBlob()` with the 'image/png' MIME type, the resulting file is often larger than the original. PNG supports a lossless compression algorithm, but the `toBlob` function doesn't offer a quality setting. To truly compress a PNG, you must manually implement the compression process, which involves creating an optimized color palette and storing pixel data as indices rather than full color values. This approach requires a deeper understanding of the PNG file format and can lead to significant file size reductions.",
  "summary": "Every online image converter I tried had the same shape: drag your file in, it uploads to a server somewhere, you get a download link back. That's fine for a meme. It's less fine for a scan of your passport, and it's the most common thing people convert. So I wanted to know how far a browser could get on its own. Quite far, as it turns out — but not without a few traps that cost me an evening…",
  "key_points": [
    "Vanilla JavaScript PNG compressor created without WASM or libraries",
    "canvas.toBlob() method can silently generate incorrect PNG files",
    "Manual compression required to achieve significant file size reduction"
  ],
  "editors_take": "Creating a PNG compressor in vanilla JavaScript enables client-side image processing for sensitive documents, bypassing server uploads, and offers finer control over compression, potentially leading to significant file size reductions.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}