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

Uploadable Laravel Package

youshido/uploadable

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Critical framing issue. The package is described as a Laravel/PHP package, but the repository (youshido-php/UploadableBundle) and its description ("Bundle brings uploadable behavor for Symfony2 Doctrine Entities") identify it as a Symfony 2 bundle, not a Laravel package. Symfony bundles rely on the Symfony FrameworkBundle, the DependencyInjection component, and the bundle registration model — none of which exist in Laravel. This is not a "port with glue code" situation; the integration surface is effectively a rewrite.

Architecture fit (Laravel): poor to none. The package's core value is a Doctrine ORM behavior: entity-level upload configuration plus event-subscriber hooks that intercept persist/update/remove to move files and set path properties on the entity. Laravel uses Eloquent, not Doctrine, and has no bundle kernel. To use this in Laravel you would need to (a) run Doctrine alongside Eloquent, (b) emulate the Symfony container/event dispatcher, and (c) reimplement the upload listener against Laravel's filesystem. At that point you have written more code than a purpose-built solution requires.

Signal quality. 1 star, 0 dependents, composite score 0.065. The 14.91 "opportunity" score should be read skeptically — with zero dependents there is no evidence of production use, no downstream compatibility validation, and no community issue history to mine for edge cases. The name/metadata mismatch (a Symfony bundle surfaced as a Laravel candidate) suggests the sourcing pipeline's classification is unreliable; treat any other recommendation from that pipeline as suspect until verified.

Technical risk. High on every axis: abandoned/EOL upstream (Symfony 2.x and 3.x are end-of-life, Doctrine annotations are deprecated in favor of attributes), no maintainer response path, likely hard PHP version ceilings in composer.json, and an implicit local-filesystem storage assumption with no adapter for S3/GCS. Upload handling is security-sensitive (MIME sniffing, path traversal, filename sanitization, executable-extension blocking); inheriting an unmaintained 1-star implementation for that responsibility is a poor risk trade.

Key questions.

  • Does the actual requirement include Doctrine at all, or is the "uploadable behavior" the only thing of interest?
  • What is the real business need: image processing, multi-storage abstraction, media library/associations, or just "store a file and a path"?
  • Are there existing entities/models on Doctrine that must be preserved, or is this greenfield?
  • What is our appetite for a spike versus adopting a maintained alternative?

Integration Approach

Stack fit. Poor. Recommend do not integrate. The equivalent capability in Laravel is well served by spatie/laravel-medialibrary, plank/laravel-mediable, or a small in-house trait + observer combination (roughly 150–300 lines) using Laravel's Storage facade, which already abstracts local/S3 and gives us temporaryUrl, streaming, and visibility controls for free.

Concept mapping, if a spike is ever warranted. Doctrine entity → Eloquent model; annotation config → model $casts/config array or PHP attributes; Doctrine prePersist/preUpdate/postRemove subscribers → Eloquent model events or an Observer; Symfony filesystem service → Illuminate\Filesystem\FilesystemManager; bundle DI config → a service provider with a published config file. Nearly every class in the bundle has a Laravel-native counterpart, which is the tell that the dependency adds translation cost without adding capability.

Migration path. Two viable routes:

  1. Greenfield (recommended): build or adopt a Laravel-native media package; treat the Symfony bundle as a design reference only.
  2. Coexistence (only if Doctrine is already mandated): run Doctrine via a bridge, keep the bundle's listener for Doctrine entities, and accept a permanently bifurcated persistence layer. This is a significant architectural tax for a single upload feature and should be rejected unless Doctrine is a hard constraint.

Compatibility. Expect composer.json constraints on symfony/framework-bundle 2.x/3.x, doctrine/orm 2.x, and PHP 5.x–7.x. These will conflict with a modern Laravel application (Laravel 10/11 requires PHP 8.1+). Verify before any spike: PHP version bounds, Doctrine ORM bounds, presence of a tagged release, last commit date, presence of tests, and license file.

Sequencing.

  1. Validate the requirement with the requesting team — confirm whether Doctrine is in scope (1–2 days).
  2. Verify package facts — read composer.json, changelog, and last-commit date; confirm the Symfony/Laravel mismatch with the requester (half a day).
  3. Decide — expected outcome is "reject dependency, adopt Laravel-native alternative."
  4. Spike a native solution — one sprint, scoped to file upload + association + storage disk + deletion cleanup.
  5. Document the decision as an ADR so the same metadata pipeline does not resurface the same candidate.

Operational Impact

Maintenance. The heaviest cost. No active upstream means we own every line we touch. Security patches for upload validation, path handling, and image parsing would fall entirely to our team on a package we did not write, have no tests for, and whose original design we cannot consult. That is a standing liability on a security-sensitive code path for zero marginal capability.

Support. No vendor, no maintainer, no issue triage, no Stack Overflow corpus for this specific bundle. Internal support would rest on whoever ran the spike, which is a bus-factor of one.

Scaling. The behavior is synchronous and local-disk oriented: files move during the request/doctrine lifecycle event, which (a) ties upload latency to request latency, (b) blocks horizontal scale on ephemeral containers unless a shared volume is mounted, and (c) provides no natural path to a CDN or object storage without replacing the storage layer. There is no queue integration, no image derivative pipeline, and no chunked/large-file handling. For a Laravel-native equivalent, the same concerns are addressed by disk abstraction, queued conversions, and Storage::temporaryUploadUrl — available off the shelf.

Failure modes to expect.

  • Non-atomic persistence: the file is written but the DB transaction rolls back (or vice versa), leaving orphaned files or broken references. This is the classic flaw in entity-lifecycle upload handlers and is not obviously addressed here.
  • Delete-on-update leaks: replacing an upload without removing the prior file accumulates unbounded storage; no reaper job is implied.
  • Unvalidated input: reliance on caller-supplied MIME/extension; risk of executable upload and path traversal via crafted filenames.
  • Memory pressure: whole-file reads for large uploads with no streaming or size ceiling.
  • Event-order fragility: behavior depends on listener priority relative to other Doctrine subscribers; silent breakage when persistence code changes.
  • Concurrency: two requests writing the same target path race with no locking.

Ramp-up. Misleadingly steep for what it does. Engineers must learn Symfony bundle conventions, Doctrine annotation mapping, and the event-subscriber lifecycle to debug a feature that in Laravel is a 200-line trait. Onboarding cost is paid by every engineer who later touches the upload path, and the knowledge does not transfer to the rest of the Laravel codebase.

Recommendation. Reject. Do not add youshido/uploadable to any Laravel application. Re-scope the requirement, adopt a maintained Laravel-native media package or a small in-house implementation, and correct the metadata classification that routed a dormant Symfony 2 bundle into a Laravel shortlist — that classification error is the more valuable finding here than the package itself.

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.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr