WP Manifestindependent plugin directory
manifest / media / indak-media-optimizer

Indak Media Optimizer releasesself-updates

WordPress plugin: converts images to lean WebP in the browser before they reach the Media Library

by Indak Media · github.com/indak-media/indak-media-optimizer · website

0stars
6release downloads
0forks

Install

The author publishes release zips, so WP-CLI can install straight from GitHub:

wp plugin install https://github.com/indak-media/indak-media-optimizer/releases/download/v0.4.0/indak-media-optimizer.zip

Ships its own WordPress updater (built-in updater), so new versions show up under Dashboard → Updates.

Readme

Indak Media Optimizer

WordPress plugin that converts images to lean WebP in the browser before they reach the Media Library. Only the web-ready file is ever uploaded, so the server never stores the 6 MB camera original.

No settings screen. Drop a JPEG/PNG anywhere WordPress accepts uploads and it arrives as a WebP, capped at 2560 px, at the lowest quality that still looks identical to the source.

What it does

Step Where Detail
Intercept Browser Hooks both upload paths WordPress uses: Plupload (Media Library, Add New, classic editor) and REST/apiFetch (block editor drops).
Resize Browser (worker) Longest edge capped at 2560 px (WordPress' own big_image_size_threshold). Never upscales. EXIF rotation honoured.
Encode Browser (worker) libwebp (WASM) searches for the lowest quality between 50 and 90 whose SSIM against the resized source is ≥ 0.93. ~2–6 encodes per image.
Upload Browser → WP The WebP replaces the original in the upload; WordPress builds thumbnails from it as usual.
Record PHP Original size/name stored as attachment meta; "Saved 84% (3.2 MB → 510 KB)" shown in attachment details and the Media list view.

Skipped (uploaded untouched): SVG, GIF, existing WebP/AVIF, video, PDF, anything the browser can't decode (HEIC in Chrome, CMYK JPEG), and any conversion that would save less than 10 %.

The single control is a checkbox under every drop zone: Upload originals (skip WebP optimization). It's remembered per browser tab only.

Images that didn't come through the uploader

Divi imports, FTP drops and site migrations write files straight into uploads/ and never touch the browser, so they skip the pipeline. For those there is Optimize now:

  • Media Library list view: an "Optimize now" row action on every eligible image, and "Optimize now" in the Bulk actions menu.
  • Attachment details (media modal, grid sidebar, Edit Media): an "Optimize now" button.

It runs the same in-browser pipeline on the existing file and swaps it in place: same attachment ID, same title/alt/caption, no new library entry. The server writes the .webp next to the old file, regenerates thumbnails, rewrites every reference to the old URLs (posts and revisions, postmeta, options — plain, serialized and JSON-escaped forms) and then deletes the old original and its thumbnails. Divi pages keep working because their image URLs now point at the WebP files.

Optimize all

For a migrated site with hundreds of images, per-page bulk selection is slow. Optimize all — on the Dashboard widget and beside "Add Media File" in the Media Library — asks the server for every image not optimized yet and runs them 2 at a time in your browser with a progress bar, running totals and a Stop button. Images that turn out to be already lean are remembered and drop out of the queue. Keep the tab open; a stop takes effect after the current image, never mid-swap.

Dashboard widget

The wp-admin Dashboard gets a Media Optimizer box: images optimized, space saved, average reduction, and how many images have not been optimized yet (with a link to the list view). Cached for an hour; refreshed on every optimization or deletion.

Install

  1. Download the latest zip from Releases (or copy this folder to wp-content/plugins/indak-media-optimizer/ — the built assets/ folder is committed, so no build step is needed either way).
  2. Activate Indak Media Optimizer in Plugins.
  3. Upload an image. Open the browser console to see the numbers per file.

Requires WordPress 6.5+, PHP 8.0+, and a server whose image library can handle WebP (GD or Imagick with WebP support — standard on Local, Hostinger, Kinsta, WP Engine). If WordPress reports it can't edit WebP, the plugin automatically uploads originals instead of failing.

Updates

Sites running this plugin get update notices in wp-admin like any wordpress.org plugin, via Plugin Update Checker (includes/Updater.php), which polls this repo's GitHub Releases.

To ship a release: bump Version: in indak-media-optimizer.php and CHANGELOG.md, commit, then tag and push:

git tag v0.2.0
git push origin v0.2.0

.github/workflows/release.yml builds assets/ and publishes a clean zip (no test/, docs/, src/, tooling) as the release asset that sites download.

Develop

npm install
npm run dev        # rebuild assets/ on every change
npm run build      # one-off production build
npm test           # Playwright tests against the built assets (see docs/TESTING.md)

Commit assets/ after building — it's what ships.

Tuning (developers only)

Override defaults from a theme or mu-plugin:

add_filter( 'indak_media_optimizer_config', function ( $config ) {
    $config['maxDimension'] = 1920;   // px, longest edge
    $config['ssimTarget']   = 0.97;   // stricter = larger files
    return $config;
} );

All keys: maxDimension, ssimTarget, qualityMin, qualityMax, convertTypes. See includes/Config.php for what each does and docs/DECISIONS.md for why the defaults are what they are.

Layout

indak-media-optimizer.php   Plugin bootstrap
includes/                   PHP: Assets (enqueue), AttachmentMeta (savings), Config (filter),
                            RestApi + Replace + OptimizeNowUi ("Optimize now"),
                            Stats + DashboardWidget, Updater (GitHub Releases)
.github/workflows/          release.yml — builds + publishes the update zip on `vX.Y.Z` tags
src/                        JS source (built by Vite into assets/)
  Main.js                   Entry: installs interceptors + toggle
  Uploader/                 InterceptPlupload, InterceptApiFetch, SkipToggle
  Pipeline/                 OptimizeFile (main-thread orchestration), Eligibility
  OptimizeNow/              OptimizeExisting (fetch → optimize → REST replace), AdminUi (buttons, bulk),
                            BatchRunner (shared queue), OptimizeAll (whole-library run)
  Compress/                 Worker, Pool, Raster, Ssim, QualitySearch (from SlimPix)
assets/                     Built output — committed
test/                       Playwright harnesses, specs, fixtures, calibrate.mjs
docs/                       ARCHITECTURE, DECISIONS, TESTING

Credits

The compression engine (src/Compress/) is lifted from Indak's SlimPix project. WebP encoding by @jsquash/webp (libwebp compiled to WASM).

Read the full README on GitHub →

Releases

TagPublishedAssetDownloads
v0.4.0 Sep 4, 2026 indak-media-optimizer.zip 3
v0.3.0 Sep 4, 2026 indak-media-optimizer.zip 1
v0.2.0 Sep 3, 2026 indak-media-optimizer.zip 1
v0.1.0 Sep 2, 2026 indak-media-optimizer.zip 1