| name | optimo |
| description | Optimize and convert images/videos with optimo, ImageMagick, and FFmpeg for JPEG/PNG/WebP/AVIF/HEIC/JXL/MP4/WebM/MOV, resize, mute, and data URLs. |
optimo
optimo reduces media size with format-specific compression pipelines.
Prerequisites
optimo resolves compressors from PATH and throws if required binaries are missing.
Required by format:
- all ImageMagick-backed formats:
magick
- SVG pipeline:
svgo
- JPEG second pass:
mozjpegtran or jpegtran
- GIF second pass:
gifsicle
- video pipeline:
ffmpeg
Quick Start (CLI)
Use npx for one-off runs:
npx -y optimo public/media
Optimize a single file:
npx -y optimo public/media/banner.png
Preserve image EXIF metadata:
npx -y optimo public/media/banner.jpg --preserve-exif
npx -y optimo public/media/banner.jpg -p
Run a dry run (no file changes):
npx -y optimo public/media/banner.png --dry-run
npx -y optimo public/media/banner.png -d
Enable lossy mode:
npx -y optimo public/media/banner.jpg --lossy
npx -y optimo public/media/banner.jpg -l
Convert and optimize to a new format:
npx -y optimo public/media/banner.png --format jpeg
npx -y optimo public/media/banner.png -f jpeg
Optimize a video:
npx -y optimo public/media/clip.mp4
Convert video format:
npx -y optimo public/media/clip.mov --format webm
Mute video audio tracks (default is already muted):
npx -y optimo public/media/clip.mp4 --mute
npx -y optimo public/media/clip.mp4 --mute false
Resize by percentage:
npx -y optimo public/media/banner.png --resize 50%
npx -y optimo public/media/banner.png -r 50%
Resize to a target max file size (images only):
npx -y optimo public/media/banner.png --resize 100kB
npx -y optimo public/media/banner.png -r 100kB
Resize by width:
npx -y optimo public/media/banner.png --resize w960
npx -y optimo public/media/banner.png -r w960
Resize by height:
npx -y optimo public/media/banner.png --resize h480
npx -y optimo public/media/banner.png -r h480
Output optimized image as data URL (single image file only):
npx -y optimo public/media/banner.png --data-url
npx -y optimo public/media/banner.png -u
Enable verbose debugging:
npx -y optimo public/media/banner.heic --dry-run --verbose
npx -y optimo public/media/banner.heic -d -v
Pipelines
optimo selects a pipeline by output format:
.png -> magick.png
.svg -> svgo.svg
.jpg/.jpeg -> magick.jpg/jpeg + mozjpegtran.jpg/jpeg (lossless JPEG without resize or conversion skips magick and runs only mozjpegtran)
.gif -> magick.gif + gifsicle.gif
- other image formats (
webp, avif, heic, heif, jxl, etc.) -> magick.<format>
- video formats (
mp4, m4v, mov, webm, mkv, avi, ogv) -> ffmpeg.<format>
Mode behavior:
- default: lossless-first pipeline
- default image behavior strips metadata/EXIF for smaller files
--lossy / -l: lossy + lossless pass where supported
--mute / -m: remove audio tracks from videos (default: true; pass --mute false to keep audio)
--preserve-exif / -p: keep image EXIF metadata in outputs
Recommended Workflow
- Start with
--dry-run to confirm target files.
- Run optimization on one file first, then scale to directories.
- Use
--format only when conversion is intended.
- Use
--resize only when explicit dimension/size control is required.
- For videos, note
--resize 100kB is not supported; use 50%, w960, or h480.
- Use
--verbose when diagnosing unsupported files or binary/flag issues.
- Verify outputs in version control before committing.
CLI Options
-d, --dry-run: Show what would change without writing files.
-f, --format: Convert output format (jpeg, webp, avif, etc.).
-l, --lossy: Enable lossy + lossless pass.
-m, --mute: Remove audio tracks from videos (default: true; use --mute false to keep audio).
-p, --preserve-exif: Preserve image EXIF metadata (default: false).
-r, --resize: Resize using percentage (50%), max file size (100kB, images only), width (w960), or height (h480).
-s, --silent: Suppress per-file logs.
-u, --data-url: Return optimized image as data URL (single image file only).
-v, --verbose: Print debug logs (pipeline selection, command execution, and errors).
Programmatic API
const optimo = require('optimo')
await optimo.file('/absolute/path/image.jpg', {
dryRun: false,
lossy: false,
preserveExif: false,
format: 'webp',
resize: '50%',
onLogs: console.log
})
await optimo.file('/absolute/path/image.jpg', {
preserveExif: true,
onLogs: console.log
})
await optimo.file('/absolute/path/image.jpg', {
resize: '100kB',
onLogs: console.log
})
await optimo.file('/absolute/path/image.jpg', {
resize: 'w960',
onLogs: console.log
})
const { dataUrl } = await optimo.file('/absolute/path/image.png', {
dataUrl: true,
onLogs: console.log
})
await optimo.file('/absolute/path/video.mp4', {
lossy: false,
mute: false,
format: 'webm',
resize: 'w1280',
onLogs: console.log
})
const result = await optimo.dir('/absolute/path/images')
console.log(result)
const { formatBytes } = require('optimo')
console.log(formatBytes(1024))
Behavior Notes
- For non-conversion runs, if the optimized file is not smaller, the original file is kept.
- During conversion, output uses the new extension and the original source file is removed (unless
--dry-run).
- Hidden files and folders (names starting with
.) are skipped in directory mode.
- Unsupported files are reported as
[unsupported] and ignored.
- Video defaults are tuned for web compatibility (
yuv420p, fast-start MP4 where applicable).
- Image outputs strip EXIF metadata by default; use
--preserve-exif or preserveExif: true to keep it.
--data-url is only supported for single image files (throws for videos or directory mode).