Super fast local image & media compression on your machine. Takes files or directories, writes *_squished.* siblings alongside the originals. Non-destructive — originals are never touched.
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/MikeDre/squish/releases/latest/download/squish-cli-installer.sh | shThis downloads the latest release for your architecture (Apple Silicon or Intel) and installs it to ~/.cargo/bin.
After installing, you still need the system dependencies for full format support (see below).
1. Install Rust (skip if rustc --version already works):
curl --proto '=https' --tlsv1.2 -sSf https://rustup.rs | shOnce the installer finishes, open a new terminal (or run source ~/.cargo/env) so that cargo is available on your PATH.
2. Install system deps and build:
./scripts/setup.sh # installs system deps via Homebrew (macOS) or apt (Linux)
cargo install --path crates/squish-cli3. Make sure squish is on your PATH:
cargo install places the binary in ~/.cargo/bin. If squish isn't found after installation, add that directory to your shell profile and reload it:
# bash
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc
# zsh
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc && source ~/.zshrcThen verify with squish --version.
GIF and HEIC support require external libraries. Install them for full format coverage:
gifsicle(required for GIF compression)- macOS:
brew install gifsicle - Linux:
apt install gifsicle
- macOS:
libheif+x265(required for HEIC/HEIF)- macOS:
brew install libheif x265 - Linux:
apt install libheif-dev libx265-dev
- macOS:
dav1d(required for AVIF decoding)- macOS:
brew install dav1d - Linux:
apt install libdav1d-dev
- macOS:
ffmpeg(required for video compression)- macOS:
brew install ffmpeg - Linux:
apt install ffmpeg
- macOS:
If a dependency is missing when you need it, squish tells you exactly what to install.
# Single file
squish dog.png
# → dog_squished.png
# Whole folder, recursively
squish ./assets/ -r
# Convert format while compressing
squish photos/ -r --format webp --quality 75
# Preserve every bit (lossless)
squish logo.svg --lossless
# Resize while compressing (never upscales)
squish photos/ -r --max-width 2000
# Fit within a box
squish hero.jpg --max-width 1920 --max-height 1080
# Preview without writing
squish ./big-folder/ -r --dry-run# Compress a video (defaults to H.265)
squish video.mp4
# → video_squished.mp4
# Use H.264 instead
squish video.mp4 --codec h264
# Fast mode — optimize without re-encoding
squish video.mp4 --fast
# Mixed batch — images and videos together
squish ./media/ -r
# → Squished 8 files (5 images, 3 videos) · 120.3 MB → 34.1 MB (-71.7%)Supported as input and output: PNG, JPEG, WebP, AVIF, SVG, GIF, HEIC, TIFF.
| Format | Library |
|---|---|
| PNG | oxipng + imagequant |
| JPEG | mozjpeg (progressive, optimized Huffman) |
| WebP | libwebp |
| AVIF | ravif (encode) + dav1d (decode) |
| SVG | usvg (compact serialization) |
| GIF (static + animated) | gifsicle -O3 |
| HEIC | libheif-rs |
| TIFF | input only — defaults to re-encoding as JPEG; use --format tiff to keep TIFF output |
Supported containers: MP4, WebM, MOV, AVI, MKV, FLV. Requires system ffmpeg.
| Codec | Flag | Notes |
|---|---|---|
| H.265 (HEVC) | --codec h265 (default) |
~50% smaller than H.264 |
| H.264 (AVC) | --codec h264 |
Maximum compatibility |
| AV1 | --codec av1 |
Best compression, slower encode |
| VP9 | auto for .webm |
Selected automatically for WebM containers |
| Copy | --fast |
No re-encode, strips metadata only |
Audio streams are copied as-is (no audio re-encoding).
Supported via ffmpeg + ffprobe: MP3, AAC/M4A, WAV, FLAC, OGG, Opus, AIFF, WebM-audio. Tags and album art are preserved by default.
| Codec | Flag | Notes |
|---|---|---|
| MP3 | --codec mp3 |
LAME VBR quality scale |
| AAC | --codec aac |
Bitrate ladder (default 192 kbps at q=80) |
| Opus | --codec opus |
Modern lossy codec; default for lossless inputs in non-interactive mode |
| Vorbis | --codec vorbis |
Quality scale, in .ogg |
| FLAC | --codec flac |
Lossless re-encode |
| ALAC | --codec alac |
Lossless, in .m4a |
By default, lossy inputs (MP3/AAC/etc) re-encode to the same codec; lossless inputs (FLAC/WAV/AIFF) prompt once for a target codec (defaults to Opus in non-interactive mode).
# Default: same codec re-encoded with sensible quality
squish track.mp3
# Convert lossless to Opus (lossy, ~50% size reduction)
squish --codec opus song.flac
# Pick a specific bitrate
squish --bitrate 192k podcast.mp3
# Strip ID3 tags and album art
squish --strip-tags album/*.mp3 -q, --quality <0-100> Quality override (default: format-specific)
--lossless Lossless compression (overrides --quality)
-f, --format <FORMAT> Output format; default preserves input format
--max-width <PIXELS> Scale down images wider than this (preserves aspect ratio)
--max-height <PIXELS> Scale down images taller than this (preserves aspect ratio)
-r, --recursive Recurse into directories
--force Overwrite existing _squished files
--suffix <NAME> Custom output filename suffix (default: squished)
--dry-run Show what would happen; don't write
-j, --jobs <N> Parallelism (default: num CPUs)
-v, --verbose Per-file output
--quiet Errors only
--codec <CODEC> Codec: video=h264|h265|av1|vp9, audio=mp3|aac|opus|vorbis|flac|alac
--fast Video: optimize without re-encoding
--bitrate <BITRATE> Audio bitrate, e.g. 128k, 192k. Overrides --quality for lossy audio
--strip-tags Strip audio metadata (ID3 tags, album art). Default: preserved
If dog_squished.png already exists, squish writes dog_squished_2.png, then _3, etc. Pass --force to overwrite instead.
cargo test # run all tests
cargo build --release # optimized binaryTest fixtures are in crates/squish-core/tests/fixtures/ (images) and crates/squish-video/tests/fixtures/ (videos). See the README in each for sources.
- Animated WebP preservation
- Smart auto-format selection
MIT.