Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Imageup Laravel Package

qcod/laravel-imageup

Laravel ImageUp is a trait that adds automatic image upload, resizing, and cropping to Eloquent models with extensive customization. Just mark image fields on your model and it handles uploads, stores paths, and deletes old images automatically.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. qcod/laravel-imageup is not a full media library — it is a trait (HasImageUploads) plus a field-options DSL that attaches image/file handling to Eloquent models. Three design decisions define the architectural fit:

  1. Save-time side effects. Uploads are wired into Model::saved(). Persisting a model can therefore write to disk, resize an image, and delete the previous file. This is convenient for CRUD scaffolding but couples persistence to HTTP request state and filesystem mutation.
  2. Implicit request coupling. Auto-upload reads request() for a same-named field (or a renamed file_input). Models become request-aware, which is the largest architectural compromise in the package.
  3. Per-field declarative config. $imageFields / $fileFields arrays carry dimensions, crop, disk, path, validation rules, filename overrides, and before_save/after_save hooks. Hooks are resolved through the Laravel IoC container (class-based) or accepted as closures, so custom logic (watermarks, blur, derivative generation) can be injected without forking.

Fit is strong for admin panels, CMS entities, profile/avatar fields, and internal tools where an Eloquent model maps 1:1 to a form. It is a weak fit for API-first services, event-sourced or queue-driven pipelines, multi-variant responsive image delivery, or anything requiring deterministic, testable persistence.

Integration feasibility. Composer-only install, auto-discovered service provider, optional publishable config/imageup.php. Required model changes are small (trait + one static property), controllers stay untouched if you accept auto-upload. php artisan storage:link is the only other prerequisite. Migration is a VARCHAR column per image field plus the URL-accessor swap in views. This is realistically a one-to-two-day change for a small set of models.

Technical risk.

  • Dependency pinning is the gating risk. The package wraps Intervention Image, and Intervention v2 → v3 is a breaking rewrite (driver configuration, ImageManager, resize/crop signatures, encoder quality). The dataset lists the latest release as 2026-08-17; verify on Packagist that the tag actually moved the intervention/image and illuminate/* constraints, because a stale constraint will cap you at an older Laravel/PHP combination.
  • Synchronous processing in the request cycle. Resize/crop runs inline on save. Large uploads (multi-MB phone photos) consume PHP memory and worker time, and GD/Imagick limits become user-facing 500s. There is no queue path.
  • Non-transactional filesystem + DB writes. File write and saved() update are not atomic. A failure between them yields orphaned files or rows pointing at missing paths. No compensating cleanup is documented.
  • Automatic deletion of prior files is a destructive default. Any retention, audit, or rollback requirement conflicts with it.
  • Validation lives in model config as rule strings. Rules are enforced on the auto-upload path but are easy to bypass on manual uploadImage() calls; this must be reconciled with FormRequest validation rather than replacing it.
  • {field}UploadFilePath() magic method naming for filename overrides is undiscoverable and silently inert if misspelled.
  • Security surface: SVG and other active content need explicit rejection; MIME sniffing and extension handling depend on your rules; public-disk paths are directly guessable — filename obscurity is the only protection.
  • Adoption signal: 767 stars but a low opportunity score and no dependents in the dataset suggest a popular-but-unmaintained-in-practice utility rather than an ecosystem standard. Treat as single-maintainer risk.

Key questions.

  1. What are the exact composer.json constraints for illuminate/support, intervention/image, and PHP, and do they include our target Laravel version?
  2. Is the latest tag a real functional release or a metadata-only bump? What changed in the changelog, and are there open issues against Intervention v3 or Laravel 10+?
  3. Does Model::saved() fire on every save (including unrelated attribute updates), and does auto-upload mis-fire on non-form saves such as seeders, imports, or queued jobs where a stale request() exists?
  4. What happens on model delete() — are image files removed, or do we inherit orphan cleanup? (Documented methods are per-field deletion only.)
  5. Are before_save/after_save hooks invoked for manual uploadImage() calls, and do they run before or after the DB path write?
  6. Which image driver is assumed (GD vs Imagick) and what are the memory ceilings for a 12 MP upload?
  7. Does the field rules string run through the Laravel validator with the same semantics as a FormRequest, including image, mimes, max (KB) and dimension rules?
  8. Is there any event, log, or exception type we can hook for observability on upload failure?

Integration Approach

Stack fit. Requires Laravel with Eloquent, the Filesystem abstraction, and the IoC container — a native fit for a conventional Laravel monolith. Works with any configured disk (public, local, s3, etc.), so S3/R2 offload is available for storage even though processing stays local. Assumes Blade/server-rendered views or an SPA that posts multipart form data with field names matching the model columns.

Migration path.

  1. Verify constraints on Packagist against our Laravel/PHP matrix; pin the exact package version and the Intervention major version in composer.json.
  2. Publish config/imageup.php; set upload_disk, upload_directory, and decide auto_upload_images globally (recommend false globally, opt in per field).
  3. Add the VARCHAR(2048)-class columns via migration; backfill existing image paths so imageUrl() resolves legacy assets.
  4. Add the trait and $imageFields to a single low-risk model (avatar/logo), with explicit rules, explicit width/height/crop, and an explicit path.
  5. Replace view-level image URL construction with imageUrl()/imageTag().
  6. Expand to further models only after the pilot clears load and failure testing.

Compatibility. Three boundaries to validate before committing:

  • Framework: Laravel version support vs. our version, and whether the service provider relies on deferred/discovery APIs still present.
  • Image driver: GD vs Imagick availability in our container/CI images; format coverage (WebP, AVIF, HEIC) differs sharply and determines whether resizing is even possible on our infrastructure.
  • Storage: storage:link on local; for S3, confirm the package writes via the Laravel disk and does not assume a local path when deleting prior files.

Sequencing. Constraint verification → pilot model in a staging environment with representative uploads (large JPEG, PNG with alpha, malicious SVG, oversized file, non-image renamed .jpg) → confirm behavior of automatic old-file deletion against our retention policy → wrap all writes behind a thin application service so the package can be replaced without touching controllers → roll out per model behind a feature flag → only then evaluate queue offloading (defer processing by disabling auto-upload and calling uploadImage() from a job).

Fallback. If constraints or maintenance stall, the substitution cost is low: spatie/laravel-medialibrary (heavier, conversions + queues + multi-variant) or a bespoke ~150-line service around Intervention Image. Keeping our own service-layer wrapper preserves that option.

Operational Impact

Maintenance. Single-maintainer, MIT, readme/changelog/releases only — no formal support contract. Budget for periodic upstream checks: Intervention and Laravel majors move faster than this package's cadence, so expect to either fork, pin, or replace at some point. The public API surface we depend on is deliberately small (trait, field options, uploadImage, imageUrl, deleteImage), which makes a future fork tractable. Low opportunity score and zero recorded dependents mean we should not assume community pressure will fix our issues.

Support. No vendor SLA; internal ownership must sit with the application team. Support load concentrates in three recurring areas: "image didn't update" (auto-upload disabled/misconfigured, or file_input name mismatch), "broken image" (disk/path or missing storage:link), and "upload failed" (validation rules or PHP memory). Document these three runbooks explicitly.

Scaling.

  • Web tier: resizing is CPU- and memory-bound per request. Concurrent large uploads are the failure mode, not request volume generally. Mitigate with strict max: rules, dimension pre-checks, and PHP memory_limit sized for the largest accepted image.
  • Storage tier: unbounded growth unless old-file deletion is on; without it, add a scheduled orphan sweeper comparing storage/ against DB columns per image field.
  • Multi-tenant / partitioned paths: achievable via per-field path or setImagesField() at runtime, but the default single upload_directory invites cross-tenant path collisions if not explicitly partitioned.
  • No CDN or responsive variants built in: imageUrl() returns one URL for one stored file. Responsive srcset, WebP/AVIF derivatives, and cache-busting must be built on top (using after_save hooks or a separate pipeline).

Failure modes.

Failure Symptom Blast radius
Disk write succeeds, DB save fails Orphaned file on disk Storage bloat, no user-visible error
DB save succeeds, disk write fails Row points to missing file Broken image in UI
Old file deleted before new file confirmed Permanent image loss Data loss, no rollback
Custom {id}-cover.jpg naming Overwrites + stale CDN/browser cache Users see old image
Non-form saves (seeders, imports, jobs) with ambient request state Unexpected uploads or silent no-ops Corrupted data during batch operations
Oversized image PHP memory exhaustion / 500 Failed save, possible partial persistence
before_save hook throws Save aborted after validation Inconsistent state if model partially written
SVG or polyglot upload with permissive rules Stored XSS via public disk Security incident

Each of these is manageable, but the default configuration is the unsafe end of the spectrum: auto-upload on, prior-file deletion on, rules optional, hooks unmonitored. Operational hardening means inverting those defaults.

Ramp-up. A Laravel-fluent developer is productive in under an hour — the README is complete for the happy path and the field-options table is self-documenting. The nontrivial learning is concentrated in the implicit behaviors: trait-driven save hooks, request coupling, the {field}UploadFilePath convention, hook ordering, and the fact that manual uploads are silently overwritten on the next save unless auto-upload is disabled. Those belong in a short internal ADR, not the upstream README.

Verdict for the record: adopt for internal, form-driven, single-image-per-field use cases with hardened defaults (auto-upload off, explicit rules, explicit disk/path, retention-aware deletion, service-layer wrapper). Do not adopt where atomicity, asynchronous processing, multi-variant delivery, or audit-grade retention are requirements — the cost of building those on top exceeds the cost of a purpose-built pipeline.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource