Asia/Kolkata
Projects

TinyCompress: Efficient Image Compression Web App

TinyCompress: Efficient Image Compression Web App – project image by Supratim Mondal
June 10, 2025
TinyCompress is a web application designed for fast, browser-based image compression and resizing. The app allows users to drag and drop multiple images, specify target file sizes (such as 50KB, 100KB, or 500KB), and download the compressed versions individually or in a zip archive. The project was built using React, TypeScript, and Tailwind CSS, with image processing handled securely via Netlify Serverless Functions and the TinyPNG developer API. Exposing a private API key (like the TinyPNG developer key) in front-end client-side requests is a major security risk. Anyone could open the browser devtools, inspect the network requests, and steal the key. To prevent this, I built a serverless backend proxy using Netlify Functions:
  • The React frontend sends the image file to the /api/compress serverless endpoint.
  • The Netlify function receives the file, retrieves the private TINYPNG_API_KEY from the server's environment variables, and forwards the file to TinyPNG's servers.
  • The compressed image is returned to the serverless function, which passes it back to the client.
TinyPNG's API compresses images but does not natively allow you to request a specific file size (e.g., "compress this image so it is exactly under 100KB"). To implement the "predefined target sizes" feature, I built a binary search scaling algorithm inside the serverless function:
  • Range: Starts with a scale factor between 0.1 (10% scale) and 1.0 (100% scale).
  • Iteration: The algorithm sends the image for compression at the midpoint scale (0.55).
  • Check: If the resulting file size is too large, the upper bound is reduced. If it is significantly smaller than the target, the lower bound is increased.
  • Limit: This repeats for a maximum of 4 iterations to find the optimal scale factor that meets the user's target size without wasting API quotas or sacrificing too much visual quality.
  • Frontend: React, TypeScript, Tailwind CSS, Framer Motion (for interface transitions)
  • File Uploads: react-dropzone
  • Backend: Netlify Serverless Functions (Node.js)
  • Image API: TinyPNG Developer API
  • Netlify Function Timeouts: Netlify's free tier limits serverless executions to 10 seconds. Running a multi-step binary search compression loop on large images (>5MB) occasionally hit this limit. To resolve this, I added client-side image pre-scaling. Before uploading, the frontend resizes large images to a maximum width of 1920px using the browser canvas API, reducing upload size and processing times by over 70%.
  • File Management: To allow downloading multiple compressed files at once, the app packages the images into a single zip file on the client side using jszip, avoiding any server-side zip creation overhead.