Skip to content

overdigo/img-turbo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 

Repository files navigation

img-turbo ⚡

High-performance image optimizer — modern successor to img-optimize, with native nginx content negotiation support.

💡 Inspiration: This project was born as an evolution of img-optimize by VirtuBox, maintaining the philosophy of simplicity and efficiency, but with modern tools, native parallelism, and production-ready features.

📖 Portuguese Version


✨ Features

Feature Description
🚀 High Performance Parallel processing on all cores (xargs -P)
📦 Modern Formats WebP, AVIF, JPEG XL with double extensions (.jpg.webp, .png.avif)
🎯 Content Negotiation Compatible naming with nginx map $http_accept
🔒 Owner Preservation Maintains www-data or other owner in multi-user environments
🛡️ Smart Validation Detects real file type (magic numbers), not just extension
📊 Complete Report Per-file savings, total space saved, and execution time
🔧 CPU Limiting --cpu-limit flag to prevent server overload

📋 Tool Comparison

Format img-optimize (original) img-turbo
JPEG jpegoptim mozjpeg — up to 20% smaller at same quality
PNG optipng (single-thread) oxipng (Rust, multithread) — up to 10× faster
WebP basic cwebp cwebp + native .webp optimization
AVIF go-avif (abandoned) avifenc (official libavif, active)
JPEG XL cjxl — lossless JPEG recompression
Parallelism ❌ serial ✅ All available cores
Double Extension .jpg.webp, .png.avif for nginx
Preserve Owner --preserve-owner for cronjobs
CPU Limit --cpu-limit for production servers

📥 Installation

macOS (Homebrew)

brew install oxipng mozjpeg webp libavif jpeg-xl

Linux

# Ubuntu/Debian (some packages may need compilation)
# Check repository availability or use brew for Linux

# Script installation
git clone https://github.com/overdigo/img-turbo.git \$HOME/.img-turbo
sudo install -m 755 \$HOME/.img-turbo/img-turbo.sh /usr/local/bin/img-turbo

🚀 Usage

Syntax

img-turbo [options] [path]

Formats

Flag Description
--jpg, --jpeg Optimize JPG/JPEG with mozjpeg (jpegtran)
--png Optimize PNG with oxipng (multithread)
--webp Convert to WebP (generates .jpg.webp, .png.webp)
--webp-opt Optimize existing WebP images (in-place)
--avif Convert to AVIF (generates .jpg.avif, .png.avif)
--jxl Convert to JPEG XL (generates .jpg.jxl, .png.jxl)
--std Optimize JPG + PNG + WebP (recommended for existing assets)
--next Generate WebP + AVIF (modern formats)
--all Everything: optimize originals + generate modern formats (excludes JXL)

Options

Flag Description Default
--path <dir> Images directory . (current)
--jobs <n> Parallelism auto (detected cores)
--jpg-quality <n> JPEG quality 82
--png-level <n> oxipng level (0-6) 4
--webp-quality <n> WebP quality 82
--avif-quality <n> AVIF quality (0-63) 30
--jxl-distance <n> JXL distance (0-15) 1.0
--no-strip Keep EXIF/XMP metadata removes
--backup Create .orig before optimizing disabled
--preserve-owner Keep original file owner/group disabled
--cpu-limit <n> Limit CPU to N% (e.g., 90)
--no-recursive Don't search subdirectories enabled
--cmin [+|-]<n> Filter: modified N minutes ago
-q, --quiet Silent mode
-h, --help Show help

💡 Examples

Basic Optimization

# Optimize JPG + PNG in current directory
img-turbo --std

# Optimize specific directory
img-turbo --std --path /var/www/html/images

# Maximum PNG compression (slower)
img-turbo --png --png-level 6 --path ./icons

Modern Format Generation (Content Negotiation)

# Generate .jpg.webp, .png.webp, .jpg.avif, .png.avif
img-turbo --next --path /var/www/images

# Complete workflow: optimize + generate all formats
img-turbo --all --path /var/www/html

# WebP only
img-turbo --webp --path ./assets

# AVIF with maximum quality
img-turbo --avif --avif-quality 20 --path ./photos

Cron Usage (Automation)

# Limit CPU to 90% to avoid affecting production server
img-turbo --all --cpu-limit 90 --preserve-owner --path /var/www/html/images

# Preserve owner (useful when script runs as different user)
img-turbo --all --preserve-owner --path /var/www/html/images

# Optimize only files modified in the last hour, with backup
img-turbo --jpg --backup --cmin -60 --preserve-owner --path /srv/uploads

# Silent processing for cronjobs
img-turbo --std --cmin -1440 --quiet --preserve-owner --path /var/www/uploads

Cronjob Example

# /etc/cron.d/img-turbo
# 90% CPU limit to avoid impacting production server
0 2 * * * www-data /usr/local/bin/img-turbo --std --cpu-limit 90 --cmin -1440 --quiet --preserve-owner --path /var/www/html/wp-content/uploads
0 3 * * * www-data /usr/local/bin/img-turbo --next --cpu-limit 90 --cmin -1440 --quiet --preserve-owner --path /var/www/html/wp-content/uploads

🔧 Nginx Integration (Content Negotiation)

img-turbo generates files with double extensions (.jpg.webp, .png.avif) to facilitate content negotiation in nginx:

# /etc/nginx/conf.d/webp-avif.conf

map \$http_accept \$webp_suffix {
    default "";
    "~*webp" ".webp";
}

map \$http_accept \$avif_suffix {
    default "";
    "~*avif" ".avif";
}

server {
    location ~* \\.(jpg|jpeg|png)\$ {
        add_header Vary "Accept";
        try_files \$uri\$avif_suffix \$uri\$webp_suffix \$uri =404;
    }
}

How it works:

  1. Client requests /image.jpg with Accept: image/avif
  2. Nginx tries: /image.jpg.avif → exists? Serve AVIF
  3. If not: tries /image.jpg.webp → exists? Serve WebP
  4. Fallback: serve original JPEG

📊 Benchmarks

JPEG — mozjpeg vs jpegoptim

File jpegoptim mozjpeg Savings
photo.jpg (2.1 MB) 1.85 MB 1.52 MB ~18% smaller

PNG — oxipng vs optipng

Scenario optipng oxipng Speed
100 PNG files ~45s ~8s ~5.6× faster

Modern Formats — Typical Savings

Format vs JPEG vs PNG
WebP -25% to -35% -15% to -30%
AVIF -40% to -55% -30% to -45%
JPEG XL -20% to -30% (lossless) -15% to -25%

🛡️ File Validation

img-turbo verifies the real file type using magic numbers, not just the extension:

✅ Incorrectly renamed files are detected
✅ PNGs with .jpg extension are ignored in JPEG worker
✅ Protection against accidental corruption

🔐 Owner Preservation

In environments where the script runs as a different user than the web server:

# Script runs as 'deploy', but files need to be 'www-data'
sudo -u deploy img-turbo --all --preserve-owner --path /var/www/images

# Or via sudoers for automation
www-data ALL=(deploy) NOPASSWD: /usr/local/bin/img-turbo

The --preserve-owner flag copies the UID/GID from the original file to the generated files.


📝 Changelog

v1.4.0

  • ✨ Explicit .jpeg support (alias for --jpg)
  • 🚀 High-scalability architecture: handles thousands of files via temporary lists (avoiding ARG_MAX limits)
  • 🛡️ Enhanced robustness: workers no longer abort the entire script on single-file failures
  • 🔧 Improved temporary file handling

v1.3.0

  • ✨ Native WebP optimization (--webp-opt)
  • 🔧 Included WebP in standard mode (--std)
  • 🔧 Removed JXL from automatic mode (--all) - now opt-in only

v1.2.0

  • ✨ Double extension for content negotiation (.jpg.webp, .png.avif)
  • --preserve-owner flag for multi-user cronjobs
  • ✨ File type validation by magic numbers
  • --cpu-limit flag for production server protection
  • 🔧 Automatic Homebrew path support

v1.1.0

  • 🚀 Parallel processing with xargs
  • 📊 Space savings report
  • 🛡️ Automatic backup with --backup

🙏 Credits

This project is an evolution of img-optimize created by VirtuBox.

We thank VirtuBox for the excellent foundation and philosophy of simplicity that inspired img-turbo. img-optimize remains an excellent choice for those seeking a lightweight and straightforward solution.


📄 License

MIT License — free to use in personal and commercial projects.


🤝 Contributing

Pull requests are welcome! Areas of interest:

  • Support for new formats (HEIC, AVIF-10bit)
  • CI/CD pipeline integration
  • Content-based parameter optimization (photo vs. illustration)

Made with ⚡ for webmasters who care about performance.

About

Fast, parallel image optimizer for nginx — generates WebP/AVIF/JPEG XL with double extensions and automatic Accept-header handling.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages