4rn0/statamic-image-editor
A Statamic addon that adds an in-control-panel image editor for cropping, resizing, rotating, and adjusting assets. Edit images directly in the CMS without leaving Statamic, with changes saved back to your files.
What it is: a Statamic addon that adds an in-control-panel image editor to the asset browser. Editors can crop, rotate, flip and resize an uploaded image without leaving the CP; the addon applies the transform server-side (Intervention Image) and writes the result back through the asset container's filesystem driver.
Install and boot
composer require 4rn0/statamic-image-editor
php artisan statamic:stache:clear
php artisan cache:clear
Statamic auto-discovers the addon's service provider — no manual config/app.php registration. If the action doesn't appear, you skipped the Stache clear; asset browser actions are registered from cached addon manifests.
Where to look first
vendor/4rn0/statamic-image-editor/src/ — the service provider's boot() shows exactly what gets registered (action, route, fieldtype or CP script), and that tells you the extension surface.php artisan vendor:publish and pick the addon's tag (check vendor/4rn0/statamic-image-editor/composer.json for the provider namespace if there's no tag). Read every key once — quality, allowed mime types and overwrite behaviour are the ones that bite.First use case: open Assets → your container → pick a photo → run the image editor action → crop → save. Then verify three things before rolling it out: the binary on disk actually changed (check the file size/timestamp on the assets disk), the Glide derivatives regenerated, and the front-end template is serving the new version rather than a cached transform. That single loop — edit, save, verify output — is the whole package in miniature.
Editorial workflow (the 80% case). Grant editors the asset edit permission on the relevant container only, and let them fix crops in place. This is the pattern the addon is built for: no re-upload, no round-trip through a designer, no orphaned files in the container.
Overwrite vs. copy. Default to a new asset (hero.jpg → hero-cropped.jpg) for anything referenced by published content, and reserve in-place overwrite for assets you know are unreferenced. In-place edits are silently destructive and there is no undo in the CP.
Re-pointing references after a copy. If editors save-as-copy, you need to move entries onto the new asset:
Asset::query()->where('container', 'assets')->where('path', 'like', '%hero-cropped%')->first();
// then per entry
$entry->set('hero_image', $newAsset->id())->save();
Wrap that in an Artisan command rather than doing it by hand — the second time you do it manually you'll miss an entry in a multisite tree.
Regenerate derivatives after edits. Treat Glide clearing as part of the edit workflow:
php artisan glide:clear
# or, if you warm presets
php artisan statamic:assets:generate
For remote containers (S3/DO Spaces), stale derivatives live in the Glide cache path on that disk, not locally — clear the right one.
Programmatic editing. Don't shell out to the CP action from application code. Use the same underlying library directly (Intervention Image v3: Image::read()->crop()->scale()->save()), and keep the addon for human-driven edits. Two code paths that both write to the same asset container should agree on quality and format settings — mirror them from the published config so they can't drift.
Presets for repeatable crops. Editorial teams crop the same shapes constantly (16:9 heroes, 1:1 avatars, 4:5 social). If the addon's JS view is publishable, add preset buttons that set the aspect ratio rather than asking editors to drag to a spec. This is the highest-value customisation and it's usually a handful of lines in the published component.
Bulk and pipeline use. For batch work (re-cropping 300 images after a redesign), skip the UI: write a one-off command using the same transform parameters. The CP editor is for one-offs; anything repetitive belongs in code, versioned, and reviewable.
^1.0, and read the diff on GitHub before upgrading production if you're on a pinned lockfile with customised published views (published assets aren't updated by composer update).edit permission. Editors who "can't see the button" almost always lack edit on that specific container — check the asset container's permissions, not the role.png/webp allowlist and never let the edit path transcode silently.php artisan statamic:stache:clear or the asset record is re-saved. This causes hours of "the edit didn't save" debugging.PutObject. A failed write often surfaces as a generic 500 in the modal; check storage/logs/laravel.log and the network tab response body, not just the toast.v1.x → v1.y requires re-diffing them.How can I help you explore Laravel packages today?