symfony/ux-cropperjs
Symfony UX Cropper.js integrates the Cropper.js image-cropping library with Symfony forms. Add a cropper-enabled form type to let users crop images in the browser and submit crop coordinates alongside uploads, with configurable options and Stimulus-powered behavior.
v3.6.0 is a maintenance release: tooling dependency updates, a README version-placeholder fix, and a Composer conflict fix for symfony/asset-mapper 8.2+. There are no API changes, no new features, and no deprecations. Treat it as a safe patch/minor upgrade.
This package is Symfony UX Cropper.js, not a Laravel-native package. For day-to-day Laravel work, first decide which layer you actually need:
Just the cropping UI? Use Cropper.js directly with Vite. This is the simplest and most Laravel-idiomatic route.
npm install cropperjs
Import cropperjs/dist/cropper.css and the Cropper constructor in your JS entrypoint, then initialise it from a Blade component.
Need the PHP-side crop model? Install the Symfony UX package for its Cropper value object, but expect to wire it manually:
composer require symfony/ux-cropperjs
Laravel will not auto-register the Symfony bundle, Twig form theme, or Stimulus controller. You can still instantiate Symfony\UX\Cropperjs\Cropper directly in a controller, job, or service.
Look first at:
vendor/symfony/ux-cropperjs/src/Cropper.php — PHP crop-data model.vendor/symfony/ux-cropperjs/assets/src/controller.ts — the Stimulus controller; useful as reference even if you use Alpine or vanilla JS.vendor/symfony/ux-cropperjs/src/Form/CropperType.php and the Twig form theme — Symfony-specific, generally not reusable in Blade.A good first use case is an avatar/image uploader: user selects an image, crops it in the browser, hidden inputs capture x, y, width, height, and the server persists both the crop metadata and a generated thumbnail.
v3.6.0 relevance: if your app also uses symfony/asset-mapper 8.2 or later, this release resolves a dependency conflict. Laravel apps using Vite are unaffected.
Blade + Alpine + Cropper.js (recommended for most Laravel apps)
Create a reusable Blade component that renders an <img>, a file input, and hidden crop fields. Initialise Cropper on file selection, and on submit copy cropper.getData() into hidden inputs. Keep the crop payload explicit and versioned:
{
"x": 120,
"y": 80,
"width": 640,
"height": 640,
"rotate": 0,
"scaleX": 1,
"scaleY": 1,
"version": 1
}
Livewire pattern
Use wire:model for the upload, then initialise Cropper after Livewire finishes morphing. Persist crop data with a Livewire action, and generate the final image in a queued job. Re-initialise on livewire:navigated and after DOM updates; otherwise the Cropper instance is orphaned.
PHP crop model pattern
If you install the Symfony UX package, use its Cropper class as a small DTO rather than expecting framework integration:
use Symfony\UX\Cropperjs\Cropper;
$cropper = new Cropper($pathToOriginalImage);
$cropper->crop($x, $y, $width, $height);
$cropData = $cropper->getCropData();
Persist $cropData as JSON. Apply it server-side with Intervention Image, Glide, or your image pipeline. Do not rely on the package to store files or manage Laravel disks.
Server-side application
Always crop from the original stored image, not the browser preview. Store crop coordinates as floats or integers consistently, clamp them to image bounds, and generate derivatives in a queued job. This keeps request latency low and makes retries safe.
Stimulus controller reuse
The package’s Stimulus controller assumes a Symfony UX/Stimulus setup. In Laravel you can either:
resources/js/controllers directory and register it with @hotwired/stimulus, orAsset and storage integration
For S3 or other remote disks, use temporary signed URLs and set Cropper’s crossOrigin option. For local disks, serve through a controller or symlink. Configure Cropper via data attributes: aspect ratio, view mode, auto-crop, background, and responsive behaviour.
v3.6.0 upgrade note
Upgrade normally. The only behavioural change is Composer dependency resolution around symfony/asset-mapper 8.2+. If you pin Symfony UX packages alongside asset-mapper, run composer update symfony/ux-cropperjs and verify the lock file. No JavaScript or PHP API migration is needed.
symfony/* dependencies. If you only need the cropper UI, install cropperjs via npm instead.symfony/asset-mapper conflict. v3.6.0 fixes a conflict with asset-mapper 8.2+. If you are on an older 3.x and also use asset-mapper, upgrade. Laravel Vite users can ignore this.crossOrigin can produce a blank or broken canvas export.How can I help you explore Laravel packages today?