Squeezit Image Optimizer
Squeezit (current stable version 1.17.0) is a versatile, lossless-first image optimization utility offered as a command-line interface (CLI), a JavaScript/TypeScript API, and a comprehensive suite of bundler plugins. It targets a wide array of modern and legacy image formats including PNG, JPEG, GIF, WebP, SVG, AVIF, HEIC, JXL, ICO, and BMP, focusing on reducing file sizes without noticeable degradation. The project exhibits active development, frequently integrating with contemporary build tools. Its key differentiators include broad format support, a user-friendly CLI with clear output, robust pattern matching for file selection (supporting shell-style and glob expressions), and a safe, threshold-based replacement mechanism to prevent unnecessary file churn. Squeezit integrates directly with ecosystems like Gulp, Grunt, Vite, Webpack, Rollup, Parcel, Astro, Next.js, esbuild, and Babel, making it suitable for a diverse range of development workflows and CI/CD pipelines.
Common errors
-
command not found: squeezit
cause The `squeezit` CLI tool is not installed globally or is not in your system's PATH.fixInstall globally with `npm install -g squeezit` or `bun add -g squeezit`. Alternatively, if installed locally, run with `npx squeezit`. -
Error: Cannot find module 'webpack' from 'squeezit/webpack'
cause A Squeezit bundler plugin (e.g., Webpack, Vite, Gulp) was used without its corresponding peer dependency installed in the project.fixInstall the missing peer dependency: `npm install webpack` (or `vite`, `gulp`, etc., depending on the plugin in use). -
Error: Image processing failed for file 'path/to/image.png': [detailed error message]
cause An unexpected issue occurred during the image optimization process, potentially due to a corrupted file, unsupported image format variant, or an internal library error.fixCheck the detailed error message for clues. Verify the image file's integrity and ensure it's a supported format. Consider reporting the issue to the Squeezit project with the full error and file details.
Warnings
- gotcha When using Squeezit's bundler plugins (e.g., for Webpack, Vite, Gulp), their respective peer dependencies (e.g., 'webpack', 'vite', 'gulp') must be installed separately in your project. Failure to do so, or using incompatible versions, will result in runtime errors. Squeezit will not install these automatically.
- gotcha The `squeezit` CLI is often installed globally (`npm install -g squeezit`). While convenient, ensure the global version aligns with any local project dependencies or specific plugin requirements to avoid unexpected behavior or command failures due to version mismatches.
- gotcha Squeezit emphasizes a 'lossless-first' approach. While it provides aggressive compression, users expecting significant file size reductions that typically come with lossy compression might find the results less dramatic than anticipated. For maximum reduction, additional lossy steps might be required.
- gotcha When using glob expressions (e.g., `images/**/*.jpg`) with the CLI, recursive scanning is not enabled by default. You must explicitly include the `-r` or `--recursive` flag for Squeezit to process files in subdirectories.
Install
-
npm install squeezit -
yarn add squeezit -
pnpm add squeezit
Imports
- optimizeFile
const { optimizeFile } = require('squeezit')import { optimizeFile } from 'squeezit' - squeezitGulp
import squeezitGulp from 'squeezit/gulp'
import { squeezitGulp } from 'squeezit/gulp' - registerSqueezitTask
import { registerSqueezitTask } from 'squeezit/grunt'const { registerSqueezitTask } = require('squeezit/grunt') - squeezitVite
const { squeezitVite } = require('squeezit/vite')import { squeezitVite } from 'squeezit/vite'
Quickstart
import { optimizeFile } from 'squeezit';
import { promises as fs } from 'fs';
import path from 'path';
async function runOptimization() {
const imagePath = path.join(process.cwd(), 'example.png');
const outputPath = path.join(process.cwd(), 'optimized-example.png');
// Create a dummy image file for demonstration if it doesn't exist
try {
await fs.access(imagePath);
} catch (error) {
console.log(`Creating dummy file at ${imagePath}`);
// Minimal PNG base64 representation (1x1 transparent PNG)
const dummyPngBuffer = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=', 'base64');
await fs.writeFile(imagePath, dummyPngBuffer);
}
console.log(`Optimizing ${imagePath}...`);
const result = await optimizeFile(imagePath, {
output: outputPath,
overwrite: true, // Overwrite if target path is the same
dryRun: false // Set to true to preview without saving
});
if (result.success) {
console.log(`Optimization successful:`);
console.log(` Original size: ${result.originalSize} bytes`);
console.log(` Optimized size: ${result.optimizedSize} bytes`);
console.log(` Reduction: ${((1 - result.optimizedSize / result.originalSize) * 100).toFixed(2)}%`);
console.log(` Output to: ${outputPath}`);
} else {
console.error(`Optimization failed: ${result.error}`);
}
// Clean up the dummy file
await fs.unlink(imagePath);
if (result.success) {
await fs.unlink(outputPath);
}
}
runOptimization().catch(console.error);