Rule of thumb: use the native encoder plus optimizer binaries in config. Write a custom encoder only when you must replace the encode step — see examples/.
Driver processes pixels
↓
Encoder writes format bytes (GD / Imagick / Libvips)
↓
Optimizer optionally post-processes those bytes (jpegoptim, cwebp, …)
↓
Storage writes the final object'optimizers' => [
'enabled' => true,
// job = serve the file first; jpegoptim/optipng/etc. overwrite later via BoldMinded Queue
// runtime = block until post-optimize finishes (useful for debugging / no queue)
'optimizeType' => 'job',
'jpeg' => 'jpegoptim',
'png' => 'oxipng',z 'webp' => null,
'avif' => null,
],Same-format post-optimizers (jpegoptim, optipng, oxipng, pngquant) can be deferred with job when the BoldMinded Queue add-on is installed. Without the queue bridge, Super Images falls back to inline (runtime) so derivatives are still optimized.
Format converters (cwebp, avifenc) always run during generation so the stored object is already the correct type.
With job, the page can return storage URLs as soon as resize/encode finishes. The queue then reads the stored object (local disk or S3 download), optimizes, and overwrites the same path/URL.
'encoders' => [
'jpeg' => ['quality' => 82],
'jpg' => ['quality' => 82],
'png' => [],
'webp' => [
'quality' => 80,
'method' => 4, // passed to cwebp as -m when using PNG→cwebp
],
'avif' => ['quality' => 65],
],'encoders' => [
'webp' => [
'quality' => 80,
'arguments' => [
'-q' => '{quality}',
'-m' => 6,
'-sharp_yuv' => true,
'-o' => '{output}',
'_' => ['{input}'], // trailing positionals
],
],
],A flat token list still works: ['-q', '{quality}', '{input}', '-o', '{output}'].
Per-format optimizer override with binary + arguments:
'jpeg' => [
'tool' => 'jpegoptim',
'binary' => $_ENV['SUPER_IMAGES_JPEGOPTIM'] ?? '/usr/bin/jpegoptim',
// Replaces the built-in recipe. Tokens: {input} {output} {quality} {effort} {method}
'arguments' => [
'--stdout' => true,
'--strip-all' => true,
'--max' => 85,
'_' => ['{input}'],
],
],| Value | Result |
|---|---|
| true or '' | Flag only (--strip-all) |
| false or null | Skipped |
| scalar | Flag + value as two argv tokens (--max, 85) |
| key ending in = | Single token (--max=85) |
| '_' / 'positional(s)' | Trailing positionals list |
| integer keys | Positional token (value only) |
arguments may also be a flat list or a whitespace-separated string. Alias key: args.
Optimizer-level arguments win over encoder-level arguments when both are set. When arguments is omitted, Super Images uses built-in recipes (jpegoptim stdout strip, cwebp with -q / -m / -sharp_yuv, etc.).
All execution goes through ProcessRunner (argument arrays only).
'optimizers' => [
'enabled' => true,
'optimizeType' => 'runtime',
'binaries' => [
'jpegoptim' => $_ENV['SUPER_IMAGES_JPEGOPTIM'] ?? 'jpegoptim',
'oxipng' => $_ENV['SUPER_IMAGES_OXIPNG'] ?? 'oxipng',
'optipng' => $_ENV['SUPER_IMAGES_OPTIPNG'] ?? 'optipng',
'pngquant' => $_ENV['SUPER_IMAGES_PNGQUANT'] ?? 'pngquant',
'cwebp' => $_ENV['SUPER_IMAGES_CWEBP'] ?? 'cwebp',
'avifenc' => $_ENV['SUPER_IMAGES_AVIFENC'] ?? 'avifenc',
],
'jpeg' => 'jpegoptim',
'png' => 'oxipng',
'webp' => null,
'avif' => null,
],Resolution order: per-format binary override → optimizers.binaries[tool] → tool name on PATH.
CP → Encoders & Optimizers shows resolved paths and an i tooltip with the apt command when something is missing.
| Tool | apt |
|---|---|
| jpegoptim | sudo apt-get install -y jpegoptim |
| optipng | sudo apt-get install -y optipng |
| pngquant | sudo apt-get install -y pngquant |
| cwebp | sudo apt-get install -y webp |
| avifenc | sudo apt-get install -y libavif-bin |
| oxipng | often via cargo; or use optipng instead |
| php-gd | sudo apt-get install -y php-gd (use php8.x-gd for your PHP version) |
| php-imagick | sudo apt-get install -y php-imagick |
| libvips | sudo apt-get install -y libvips42 libvips-dev then composer require jcupitt/vips |
SUPER_IMAGES_JPEGOPTIM=/usr/bin/jpegoptim
SUPER_IMAGES_CWEBP=/usr/bin/cwebp
SUPER_IMAGES_OXIPNG=/usr/bin/oxipngIf an env var is empty, Super Images falls back to the tool name and searches PATH. Use $_ENV['…'] in config (ExpressionEngine loads .env into $_ENV).
JPEG does not support transparency. When the source has an alpha channel, all drivers flatten onto a white background (#ffffff) before JPEG encode so output matches WebP/AVIF visually (no “ghost” overlay).
Override the flatten colour via encoder extra.background if needed.
php eecli.php super_images:doctor