<?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: Siddhartha Mondal</title>
    <description>The latest articles on DEV Community by Siddhartha Mondal (@siddhartha_mondal).</description>
    <link>https://dev.to/siddhartha_mondal</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4203225%2Feb89e3c9-5088-4514-a6a6-bd3b4d4fe9aa.png</url>
      <title>DEV Community: Siddhartha Mondal</title>
      <link>https://dev.to/siddhartha_mondal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/siddhartha_mondal"/>
    <language>en</language>
    <item>
      <title>I built a browser-only image toolkit with React and Canvas (no server needed)</title>
      <dc:creator>Siddhartha Mondal</dc:creator>
      <pubDate>Fri, 23 Oct 2026 18:31:46 +0000</pubDate>
      <link>https://dev.to/siddhartha_mondal/i-built-a-browser-only-image-toolkit-with-react-and-canvas-no-server-needed-36jp</link>
      <guid>https://dev.to/siddhartha_mondal/i-built-a-browser-only-image-toolkit-with-react-and-canvas-no-server-needed-36jp</guid>
      <description>&lt;p&gt;Most "free online image tools" upload your files to a server, keep them for some period, and often want an account. I wanted the opposite: every operation runs on your device, nothing is transmitted to a backend, and no account is required.&lt;/p&gt;

&lt;p&gt;That's why I built &lt;strong&gt;PixelShrink&lt;/strong&gt; — a browser-only image toolkit that runs entirely on the Canvas API.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Compress JPG, PNG, and WebP images&lt;/li&gt;
&lt;li&gt;Resize, crop, and convert between formats&lt;/li&gt;
&lt;li&gt;Compress to a target file size (100 KB, 200 KB)&lt;/li&gt;
&lt;li&gt;Batch compress and download results as a ZIP&lt;/li&gt;
&lt;li&gt;Combine images into a PDF&lt;/li&gt;
&lt;li&gt;Inspect and strip EXIF metadata&lt;/li&gt;
&lt;li&gt;Generate favicons, social-media presets, and passport sizes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;17 tools in total, all client-side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why browser-only matters
&lt;/h2&gt;

&lt;p&gt;Image compression isn't expensive. It's a CPU operation that any laptop can do in milliseconds. There's no technical reason to send a 3 MB photo to a server and back.&lt;/p&gt;

&lt;p&gt;The reasons tools do it anyway are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They want to show you an ad before the download.&lt;/li&gt;
&lt;li&gt;They want your email for their marketing list.&lt;/li&gt;
&lt;li&gt;They want to upsell you to a paid plan.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Browser-only tools remove all three. The image never leaves your device. No upload, no account, no tracking.&lt;/p&gt;

&lt;h2&gt;
  
  
  The technical stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React + TypeScript&lt;/strong&gt; for the UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vite&lt;/strong&gt; for the build&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt; for styling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canvas API&lt;/strong&gt; for all image processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pdf-lib&lt;/strong&gt; for the image-to-PDF tool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jszip&lt;/strong&gt; for batch downloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;react-image-crop&lt;/strong&gt; for the cropper&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;exifr&lt;/strong&gt; for metadata reading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything is lazy-loaded per route, so the home page loads in under 100 KB.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hardest part
&lt;/h2&gt;

&lt;p&gt;Two things were genuinely tricky:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Format detection&lt;/strong&gt; Browsers don't all support the same encoder set. Safari can encode WebP and AVIF, Firefox can encode WebP but AVIF support varies, and old browsers can't encode either. Rather than claim "AVIF supported!" and then silently fall back to PNG, the site runs a 2×2 test canvas through &lt;code&gt;toBlob&lt;/code&gt; at runtime and only offers formats the browser can actually produce.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;2. Touch-friendly cropping.&lt;/strong&gt; Getting a crop box to feel right on a phone — drag to resize, drag inside to move, snap to aspect ratio — is harder than it looks with raw pointer events. I used &lt;code&gt;react-image-crop&lt;/code&gt; rather than rolling my own, and it handles the touch edge cases correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I deliberately didn't do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No server-side processing.&lt;/strong&gt; That would break the "no uploads" promise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No AI upscaling.&lt;/strong&gt; The upscaler uses plain canvas interpolation and says so on the page. Faking "AI enhancement" would be dishonest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No HEIC support.&lt;/strong&gt; Browsers can't decode HEIC without a large WASM bundle. I'd rather say "not supported" than ship a broken tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No analytics or ads (yet).&lt;/strong&gt; If I ever add them, the privacy policy will be updated first.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://pixelshrink-tools.netlify.app/" rel="noopener noreferrer"&gt;https://pixelshrink-tools.netlify.app/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No account, no uploads, no tracking. Free.&lt;/p&gt;

&lt;p&gt;I'd love feedback — especially on the touch experience and on any format the site doesn't handle that you wish it did.&lt;/p&gt;

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