r64/nova-image-cropper
A Laravel Nova field for cropping images directly in the admin panel. Upload, adjust the crop area, and save precise dimensions for avatars, banners, thumbnails, and other image assets with a simple, intuitive workflow.
Build vs. buy for admin tooling. An interactive cropper is commodity capability — zero differentiation, real engineering hours. Adopting this field replaces a hand-rolled Nova/Vue cropping component with one dependency at effectively zero licensing cost. The decision worth making isn't "should we build a cropper," it's "are we willing to spend a sprint building one anyway."
Unblocking media-dependent features. A crop UI is usually the last gate between "we have a file upload field" and shipping avatars, product thumbnails, editorial hero images, marketplace listing photos, and banner assets. This package is the unblocker for that whole class of roadmap work — one field, one afternoon, feature moves.
Enforcing layout integrity as a product rule, once. Fixed aspect ratios and crop dimensions applied at upload time prevent distorted heroes, ragged gallery grids, and the CSS patches that follow them. That's a UX consistency decision made at the admin layer a single time instead of repeatedly in the frontend — and it moves image-quality cleanup from design/support tickets to the point of upload.
Reinforcing the back-office platform bet. Every Nova-native field adopted deepens the Nova commitment and shrinks custom admin code the team must own. This is a small, low-controversy vote in that direction — worth naming explicitly so it isn't mistaken later for an accidental architecture decision.
A reversible decision, deliberately kept that way. Cropping happens in the browser and the server receives an already-cropped file, so this sits purely at the UI layer with a credible exit path. Frame and approve it as a tactical accelerant, not a platform commitment; the cost of being wrong is contained to a field swap.
Use-case fit: e-commerce catalogs, editorial/CMS workflows, marketplace listings, and profile management — anywhere non-technical staff upload images and the product requires predictable dimensions.
Adopt when:
Look elsewhere when:
intervention/image, spatie/image, or Cropper.js directly instead.To executives: This is a small, cheap, reversible purchase of speed. It gets image-cropping out of the backlog and into the admin panel without a custom build, and it lets us enforce consistent image dimensions at the point of upload — which means fewer design and support cycles spent fixing distorted hero images and ragged galleries. Cost is a single Composer dependency; the exit path is a field swap if we change our minds. The one caveat to acknowledge honestly: it's a community package with no vendor behind it, so we're accepting a small maintenance obligation in exchange for a sprint of engineering time.
To engineering: It's a Nova field that wraps Cropper.js in the browser and persists through Nova's normal file-upload path — no GD/Imagick, no server-side image processing, no new infrastructure. Two things to own deliberately: pin the version (no floating constraints) and decide the overwrite policy before rollout — if the installed version replaces the original in place, an editor re-cropping a hero image destroys the source, so we keep a separate original column or hideWhenUpdating() it. Centralise crop/preview dimensions in config from day one via a thin helper rather than hard-coding them across resources; that single seam also makes the package replaceable and contains any method rename to one file. Add a CI check that boots Nova and instantiates the field so a Nova upgrade fails loudly, plus one test that asserts output dimensions on a rotated fixture — silent no-op crops look like success and are the failure mode to design against.
Sequencing we're approving: one resource → disk config → sizing centralisation → derivative policy → overwrite/backfill decision → observability. Not inverting the last two is what keeps this from becoming a data-loss incident.
How can I help you explore Laravel packages today?