We built an all-in-one WordPress image toolkit. Here's the architecture behind it The team behind ImageCraft, an open-source WordPress plugin, has detailed the architecture of their all-in-one image toolkit, which combines AI alt text generation, compression, and WebP conversion into a single codebase. The plugin connects directly to AI providers like Anthropic, OpenAI, and Google Gemini, avoiding credit-based middlemen, and performs on-server compression using Imagick to reduce costs and improve efficiency. We want to talk about why most WordPress image plugins exist as separate, single-purpose tools — and why we think that's the wrong approach. If you manage WordPress sites, you've probably installed some combination of these: an AI alt text generator, a compression plugin, a WebP converter, a media file renamer, and maybe something to catch broken images. Each one solves a real problem. But together, they create new ones. They fight over hook priority on wp get attachment image . They store overlapping metadata without knowing about each other. They enqueue separate admin scripts on the same pages. And when one of them breaks on a WordPress update, you're debugging a five-plugin interaction. ImageCraft is our answer to this. One plugin, one pipeline, every image optimization task in a single codebase. It's free and open source on WordPress.org. We want to walk through the technical decisions, because we think they're more interesting than a feature list. Most AI alt text plugins work on a credit model. You buy credits from the developer, they proxy your request to OpenAI or Claude, and pocket the margin. The markup is significant — GPT-4o-mini costs about $0.15 per 100 images at retail, but credit-based plugins charge $3–6 for the same volume. ImageCraft connects directly to the AI provider from your server. No middleman, no credit packs. You pay the provider at their published rates. Three providers are supported: Anthropic Claude , OpenAI, and Google Gemini. Each extends a BaseAIProvider class that handles image fetching, base64 encoding, MIME detection, and prompt construction. Adding a new provider means implementing one method: generateAltText . API keys are AES-256-CBC encrypted in a custom database table. The REST API never returns the key — only a boolean has key field. A naive implementation would make separate API calls for alt text, title, and caption. Three network round trips, three token charges, three latency waits. ImageCraft makes one call that returns all three in a structured JSON response: { "alt text": "Tan leather crossbody bag with brass buckle and adjustable strap", "title": "Aria Crossbody Bag - Tan Leather", "caption": "Handcrafted crossbody bag from the Aria Collection, featuring full-grain tan leather and antique brass hardware." } The prompt instructs the model to return this exact shape. A parseMetaJson helper handles the response — including edge cases like markdown-wrapped JSON, extra fields, and truncated responses. Each field has a configurable max length with a capText function that truncates at the last word boundary rather than mid-word. For WooCommerce images, the prompt includes product metadata name, SKU, categories, price before the image, so the model writes with product context rather than describing the image generically. Most compression plugins — ShortPixel, Imagify, TinyPNG — upload your images to an external API, compress them there, and download the result. This makes sense if your server doesn't have good image libraries. But most modern hosts have Imagick installed, and it's plenty capable. ImageCraft compresses directly on the server: That last step is important. Some already-optimized images especially PNGs with good compression get larger after re-encoding. The never-enlarge guard prevents this silently. Originals are backed up to wp-content/uploads/icais-originals/ with the same directory structure. One-click restore copies the backup over the compressed version. php // Simplified never-enlarge guard $tempPath = $this- compressToTemp $sourcePath, $quality ; if filesize $tempPath = filesize $sourcePath { unlink $tempPath ; return; // original is already optimal } There are broadly three ways to serve WebP on WordPress: Rewrite rules — .htaccess or nginx config that serves a .webp file when the browser sends Accept: image/webp . Fragile. Breaks on some hosts. Requires server-level config. URL replacement — change the image URL in the HTML from .jpg to .webp . Breaks caching. Confuses CDNs. Hard to reverse.