
12 Free Image Tools Every Web Developer Should Bookmark
Twelve genuinely free image tools - Squoosh, Sharp, ImageMagick, FFmpeg, SVGO, oxipng, MozJPEG, ExifTool, DevTools and more - with the exact commands and the job each one is best at.
Every tool on this list is free, actively maintained, and does one job properly. There are no trial limits, no watermarks, and no “free for the first 100 images” tiers.
They fall into four groups: things you open in a browser, command line tools, libraries you script against, and auditing tools. Most workflows need one from each group.
Quick Index
| # | Tool | Type | Best at |
|---|---|---|---|
| 1 | Squoosh | Browser | Comparing encoders visually, one image at a time |
| 2 | ImageGuide tools | Browser | Quick conversions with no upload |
| 3 | Sharp | Node library | Production image pipelines |
| 4 | ImageMagick | CLI | Anything, especially odd one-off transforms |
| 5 | FFmpeg | CLI | GIF to video, animated formats, frame extraction |
| 6 | cwebp and avifenc | CLI | Reference-quality WebP and AVIF encoding |
| 7 | MozJPEG | CLI | The smallest JPEGs available |
| 8 | oxipng and pngquant | CLI | Lossless and lossy PNG reduction |
| 9 | SVGO | CLI | Stripping 40–70% from exported SVGs |
| 10 | ExifTool | CLI | Reading and stripping metadata |
| 11 | Chrome DevTools | Browser | Finding what is actually slow |
| 12 | Lighthouse and PageSpeed Insights | Browser/CLI | Prioritising what to fix |
1. Squoosh
squoosh.app · Browser · No upload
Google’s encoder playground, and the fastest way to answer “what does quality 72 actually look like?” It runs every encoder as WebAssembly in your browser, so nothing leaves your machine.
What Makes It Worth Keeping Open
- Side-by-side split view with a draggable divider, at real pixel scale
- Every major encoder: MozJPEG, OxiPNG, WebP, AVIF, JPEG XL, QOI
- Live file size as you drag the quality slider
- Resize, reduce palette, and change colour space in the same pass
Use It To Find Your Quality Settings
Squoosh is not a batch tool and should not be. Its job is to establish the settings you then apply in a pipeline. Load one representative image per content category, find the point where quality drops become visible, back off two points, and write that number down.
| Content category | Find the knee once | Then apply everywhere |
|---|---|---|
| Product on white | Squoosh | Sharp or a CDN |
| Editorial photography | Squoosh | Sharp or a CDN |
| Screenshots | Squoosh | Sharp or a CDN |
| Illustrations | Squoosh | SVGO or pngquant |
2. ImageGuide’s Browser Tools
/tools/ · Browser · No upload
Our own converters run entirely in the browser using WebAssembly and JavaScript. Files never reach a server, which matters when the document is a contract, a medical scan, or an unreleased product shot.
| Tool | Job |
|---|---|
| Compress | Reduce file size with a live preview |
| Analyze | Inspect dimensions, format, and metadata of any image |
| Compare | Slide between two versions at full resolution |
| MP4 to GIF | Convert video to GIF when a platform demands one |
| GIF to MP4 | The conversion you should be doing far more often |
| Image to PDF | Combine images into a single document |
| PDF to JPG | Extract pages as images |
| HEIC to PDF | Handle iPhone photos without installing anything |
Because the work happens locally, the practical size limit is your device’s memory rather than an upload cap.
3. Sharp
Node library · npm install sharp
The default choice for production image processing in JavaScript. Sharp wraps libvips, which is dramatically faster and uses far less memory than ImageMagick for the resize-and-encode work that web pipelines actually do.
The Pipeline You Will Write Most Often
import sharp from 'sharp';
const WIDTHS = [400, 800, 1200, 1600];
async function derive(input, basename) {
const jobs = [];
for (const width of WIDTHS) {
const base = sharp(input)
.rotate() // apply EXIF orientation
.resize({ width, withoutEnlargement: true });
jobs.push(
base.clone().avif({ quality: 58 }).toFile(`${basename}-${width}.avif`),
base.clone().webp({ quality: 80, effort: 6 }).toFile(`${basename}-${width}.webp`),
base.clone().jpeg({ quality: 82, progressive: true, mozjpeg: true }).toFile(`${basename}-${width}.jpg`)
);
}
return Promise.all(jobs);
}
Details That Save Time Later
.rotate()with no argument applies the EXIF orientation and then drops the tag. Without it, portrait phone photos come out sideways.- Metadata is stripped by default. Use
.withMetadata({ icc: 'srgb' })only if you need the profile. mozjpeg: trueuses the better JPEG encoder with no extra install.- Streams work, so you can process an upload without writing it to disk.
// Resize an upload stream on the way through
request.pipe(
sharp().resize({ width: 1600, withoutEnlargement: true }).webp({ quality: 80 })
).pipe(response);
4. ImageMagick
CLI · magick (v7) or convert (v6)
Thirty-five years old and still the tool that can do the thing no other tool can. ImageMagick is slower and heavier than Sharp for bulk resizing, but it handles hundreds of formats and every transform you can name.
The Commands Worth Memorising
# Resize, capping the long edge, never upscaling
magick in.jpg -resize '1600x1600>' -quality 85 out.jpg
# Pad to a square canvas with even margins
magick product.jpg -resize 1700x1700 -background white -gravity center \
-extent 2000x2000 product-square.jpg
# Strip all metadata
magick in.jpg -strip out.jpg
# Convert a CMYK print master to web sRGB
magick master.tif -colorspace sRGB -resize 1600x1600\> -quality 88 web.jpg
# Force 4:4:4 chroma for a screenshot with coloured text
magick screenshot.png -sampling-factor 1x1 -quality 90 screenshot.jpg
# Report dimensions, format and size for every file in a folder
magick identify -format "%f %wx%h %[size] %m\n" *.jpg
# Build a multi-size favicon
magick icon-256.png -define icon:auto-resize=16,32,48 favicon.ico
# Flatten transparency onto white before converting to JPEG
magick in.png -background white -alpha remove -alpha off out.jpg
The > in '1600x1600>' means “only shrink, never enlarge”. Quote it in most shells, or escape it as 1600x1600\>.
5. FFmpeg
CLI · ffmpeg
Known as a video tool, but it is the correct answer to several image problems, above all the GIF problem.
Replace a GIF With Video
ffmpeg -i animation.gif -movflags faststart -pix_fmt yuv420p \
-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" animation.mp4
yuv420p and the even-dimension scale filter are both required for broad playback compatibility. A 4 MB GIF typically becomes a 180 KB MP4.
Other Jobs FFmpeg Does Well
# Extract a poster frame at 2 seconds
ffmpeg -ss 2 -i clip.mp4 -frames:v 1 -q:v 2 poster.jpg
# Build an animated WebP from a video
ffmpeg -i clip.mp4 -vcodec libwebp -lossless 0 -q:v 60 -loop 0 clip.webp
# Turn a folder of stills into a video (product spin, timelapse)
ffmpeg -framerate 24 -pattern_type glob -i 'frames/*.jpg' \
-c:v libx264 -pix_fmt yuv420p spin.mp4
# Extract every frame of a GIF as PNG
ffmpeg -i animation.gif frames/frame-%03d.png
# Make a genuinely small GIF, when you truly must have a GIF
ffmpeg -i clip.mp4 -vf "fps=12,scale=480:-1:flags=lanczos,palettegen" palette.png
ffmpeg -i clip.mp4 -i palette.png -lavfi "fps=12,scale=480:-1:flags=lanczos [x]; [x][1:v] paletteuse" out.gif
That last two-pass palette technique cuts GIF size roughly in half compared to a naive single-pass conversion.
6. cwebp and avifenc
CLI · From libwebp and libavif
The reference encoders. Every other WebP and AVIF tool wraps one of these, so going direct gives you every option and the most predictable output.
cwebp
# Lossy photograph, maximum compression effort
cwebp -q 80 -m 6 photo.jpg -o photo.webp
# Lossless, for screenshots and flat art
cwebp -lossless -z 9 screenshot.png -o screenshot.webp
# Keep alpha crisp on a logo
cwebp -q 85 -alpha_q 100 logo.png -o logo.webp
# Near-lossless: much smaller than lossless, visually identical
cwebp -near_lossless 60 diagram.png -o diagram.webp
-near_lossless is underused. On diagrams and UI captures it often produces half the size of true lossless with no visible difference.
avifenc
# Balanced photograph
avifenc --min 0 --max 63 -a end-usage=q -a cq-level=30 -s 6 in.png out.avif
# Higher quality, slower
avifenc --min 0 --max 63 -a end-usage=q -a cq-level=24 -s 4 in.png out.avif
# Text and diagrams: full chroma resolution
avifenc --yuv 444 -a cq-level=20 diagram.png diagram.avif
# Lossless
avifenc --lossless in.png out.avif
Lower cq-level means higher quality. Roughly, cq-level=30 corresponds to JPEG quality 85. The -s speed flag trades encode time for compression: -s 0 is slowest and smallest, -s 10 is fastest and largest.
7. MozJPEG
CLI · cjpeg and jpegtran from mozjpeg
Mozilla’s JPEG encoder produces files 8% to 15% smaller than standard libjpeg at identical visual quality, using trellis quantization and better progressive scan scripts. The output is a completely ordinary JPEG that every decoder reads.
# Encode with MozJPEG
cjpeg -quality 82 -progressive -optimize -outfile out.jpg in.ppm
# Losslessly re-optimize an existing JPEG: pixel-identical, 3-8% smaller
jpegtran -copy none -optimize -progressive -outfile out.jpg in.jpg
jpegtran is the safest optimization in this entire guide. It does not decode and re-encode, so there is zero generation loss. Running it over an existing JPEG library is free bytes.
# Optimize every JPEG in place, recursively
find . -name '*.jpg' -exec sh -c \
'jpegtran -copy none -optimize -progressive -outfile "$1.tmp" "$1" && mv "$1.tmp" "$1"' _ {} \;
Sharp exposes the same encoder with mozjpeg: true, so you rarely need the binary in a Node pipeline.
8. oxipng and pngquant
CLI · Two tools, two different jobs
People confuse these constantly. They do opposite things and work well together.
| Tool | Lossy? | What it does |
|---|---|---|
oxipng |
No | Finds a better lossless encoding of the same pixels |
pngquant |
Yes | Reduces the image to a 256-colour palette |
# Lossless: pixel-identical output, typically 10-30% smaller
oxipng -o 4 --strip safe in.png
# Lossy palette reduction: often 60-70% smaller on flat art
pngquant --quality 65-90 --speed 1 illustration.png
# Both, in the right order
pngquant --quality 65-90 --speed 1 --output tmp.png illustration.png
oxipng -o 4 --strip safe tmp.png && mv tmp.png illustration-final.png
Run pngquant first, then oxipng. Reducing the palette makes the lossless pass more effective.
pngquant is right for illustrations, icons, and flat graphics. It is wrong for photographs and for screenshots with subtle gradients, where 256 colours produce visible banding.
9. SVGO
CLI · npx svgo
Design tools export enormous SVGs. Figma, Illustrator, and Sketch all embed editor metadata, unnecessary coordinate precision, empty groups, and duplicated definitions. SVGO removes 40% to 70% of a typical exported file with no visual change.
# Single file
npx svgo --multipass icon.svg -o icon.min.svg
# Whole directory, in place
npx svgo --multipass -f ./src/icons
# Keep the viewBox, which SVGO removes by default and which you almost always need
npx svgo --multipass --disable=removeViewBox icon.svg -o icon.min.svg
The One Setting You Must Change
SVGO’s default config removes viewBox when width and height are present. That breaks scaling: the SVG becomes fixed-size instead of fluid. Always disable that plugin, or use a config file:
// svgo.config.js
export default {
multipass: true,
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false,
cleanupIds: false // keep IDs if you reference them from CSS or JS
}
}
}
]
};
Disable cleanupIds too if you target elements inside the SVG from CSS or script. See the SVG best practices guide.
10. ExifTool
CLI · exiftool
The definitive metadata tool. It reads, writes, and strips every metadata standard in every format, and it is the correct tool for the privacy side of image handling.
# See everything in a file
exiftool photo.jpg
# Check specifically for location data
exiftool -gps:all photo.jpg
# Strip everything, restore orientation so the photo stays upright
exiftool -all= -tagsFromFile @ -Orientation -overwrite_original photo.jpg
# Strip an entire tree, recursively
exiftool -all= -tagsFromFile @ -Orientation -r -overwrite_original ./uploads
# Keep copyright and creator, drop everything else
exiftool -all= -tagsFromFile @ -Copyright -Artist -Orientation -overwrite_original photo.jpg
# Report which files in a folder still carry GPS data
exiftool -filename -gpslatitude -gpslongitude -if '$gpslatitude' -r ./uploads
That last command is worth running against any directory of user uploads. GPS coordinates in a public photo expose where it was taken. See the metadata and privacy guide.
11. Chrome DevTools
Browser · Already installed
Free, and the only tool here that tells you what is actually happening to a real visitor.
The Four Panels That Matter
Network → filter Img. Right-click the column headers and add Dimensions. Sort by size. Anything served much larger than it displays is a wasted download.
Elements. Hover an <img> to see its rendered box next to its intrinsic size. The tooltip shows both.
Performance → LCP marker. Shows which element is your LCP and when it finished. Click it to jump to the element.
Coverage. Not for images directly, but it reveals CSS that references background images the page never shows.
The Console One-Liner
[...document.querySelectorAll('img')]
.map(img => ({
src: img.currentSrc.split('/').pop(),
natural: `${img.naturalWidth}x${img.naturalHeight}`,
rendered: `${Math.round(img.clientWidth)}x${Math.round(img.clientHeight)}`,
overSizedBy: +(img.naturalWidth / (img.clientWidth * devicePixelRatio || 1)).toFixed(1),
lazy: img.loading === 'lazy',
priority: img.fetchPriority
}))
.sort((a, b) => b.overSizedBy - a.overSizedBy)
.forEach(r => console.table([r]));
Also throttle to Slow 4G in the Network panel before judging anything. Local development on a fast connection hides every image problem you have.
The DevTools debugging guide goes through each panel in detail.
12. Lighthouse and PageSpeed Insights
Browser, CLI, and web · Free
Lighthouse tells you which image problems are worth your time. PageSpeed Insights runs the same audits and adds field data from real Chrome users, which is the number that actually affects rankings.
The Image Audits
| Audit | Means |
|---|---|
| Properly size images | Serving more pixels than the display uses |
| Efficiently encode images | Quality set too high, or a poor encoder |
| Serve images in next-gen formats | No WebP or AVIF offered |
| Defer offscreen images | Below-fold images not lazy loaded |
| Image elements do not have explicit width and height | CLS risk |
| Largest Contentful Paint image was lazily loaded | The single most costly image mistake |
| Avoid enormous network payloads | Usually images |
Run It In CI
npm install -g @lhci/cli
lhci autorun \
--collect.url=https://example.com/products/walnut-desk-lamp \
--assert.assertions.uses-responsive-images=error \
--assert.assertions.modern-image-formats=error \
--assert.assertions.unsized-images=error
Lab data from Lighthouse is reproducible but synthetic. Field data in PageSpeed Insights and the Chrome UX Report is noisy but real. Fix what lab data finds, then confirm with field data over the following month. See the Lighthouse audit guide.
Putting a Stack Together
You do not need all twelve. Three sensible combinations:
Small Site, Manual Workflow
- Squoosh to find quality settings
- ImageGuide tools for one-off conversions
- Lighthouse to check the result
Node Project With a Build Step
- Squoosh to establish settings
- Sharp in the build
- SVGO for icons
- Lighthouse CI as a gate on pull requests
Large Catalogue or User Uploads
- Sharp or ImageMagick for ingest normalisation
- ExifTool to strip metadata from uploads
- FFmpeg for anything animated
- An image CDN for delivery, so you stop generating variants entirely
That last point is where free tools stop being the cheapest option. Generating four widths in three formats means twelve files per image, plus the storage and the rebuild whenever you add a breakpoint. Sirv does the resizing and format negotiation per request from one original, which removes the pipeline rather than optimising it. The CDN comparison covers the trade-off honestly, including when a build step is genuinely the better answer.
Summary
By Job
| Job | Tool |
|---|---|
| Find the right quality setting | Squoosh |
| Convert one file, nothing installed | ImageGuide tools |
| Resize and encode in a Node pipeline | Sharp |
| Any transform, any format | ImageMagick |
| Replace a GIF with video | FFmpeg |
| Reference WebP and AVIF encoding | cwebp, avifenc |
| Smallest possible JPEG | MozJPEG |
| Shrink a PNG | pngquant then oxipng |
| Shrink an SVG | SVGO |
| Read or strip metadata | ExifTool |
| Find what is slow | Chrome DevTools |
| Decide what to fix first | Lighthouse, PageSpeed Insights |
Checklist
- ✅ Quality settings were established in Squoosh, not guessed
- ✅ A library (Sharp) does the bulk work, not a manual tool
- ✅
jpegtranhas been run over the existing JPEG library - ✅ Every SVG goes through SVGO with
removeViewBoxdisabled - ✅
pngquantruns beforeoxipng, not after - ✅ Uploads are stripped of GPS data with ExifTool
- ✅ No GIFs survive: FFmpeg has converted them to MP4
- ✅ DevTools was used with throttling on, not on a fast local connection
- ✅ Lighthouse image audits run in CI, not just by hand
Start with Squoosh and DevTools. One tells you what good looks like, the other tells you where you are not achieving it.
Related Resources
Related Guides
Image Compression Tools Compared: TinyPNG vs Squoosh vs ShortPixel & More
Batch Image Processing Workflows: Scale Your Optimization
Browser DevTools for Image Debugging: Complete Guide
Lighthouse Image Audit: Fix Every Image Warning
Build Tool Image Plugins Compared
9 Ways to Reduce Image File Size Without Losing Quality