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

File Manager Laravel Package

proside/file-manager

Reusable file manager for Laravel 10/11/12 built in Livewire v4: directory tree, grid/list views, uploads, drag & drop, trash with restore, previews, search, multi-disk support and a file picker component. No iframe or external service.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

This is a conventional Laravel package with an unusually clean boundary. The surface area is small and legible: a service provider (auto-discovered), one Livewire component, a handful of Blade partials and components, a FileManagerService for filesystem operations, a MediaController serving media over a named route, and one Artisan command (file-manager:prune-trash). There is no second runtime, no external service, no token exchange.

The architectural win versus the legacy Next.js/React implementation is that the entire class of failure modes around the iframe + postMessage + JWT RS256 + .pem key rotation + CORS + reverse-proxy disappears. Authorization collapses into Laravel's existing session and middleware, and filesystem access is confined server-side by PathGuard. For a server-rendered Blade/Livewire application, this is close to the ideal shape for the problem — a file manager is fundamentally a stateful, permissioned view over a filesystem, and Livewire models that more directly than a decoupled SPA.

The architectural misfit is equally clear: if the target application is Inertia/React/Vue or API-first, embedding a Livewire v4 component means running two frontend paradigms in one product, and the <x-file-manager::picker> drop-in value proposition evaporates because there are no Blade forms to drop it into.

Integration feasibility

Installation is genuinely four commands: composer require, storage:link, optional vendor:publish, and a Tailwind content entry. Package discovery removes the usual provider/route registration chores. The picker preserves the legacy prop API (input-name, :value, multiple, filter) and writes to a plain hidden input, so existing form requests, $model->update() calls and validation rules keep working — the migration cost is concentrated in the UI layer, not in controllers or models.

Two integration gates are real and must be resolved before any commitment:

  1. Livewire ^4.0 is a hard requirement. The package does not merely prefer Livewire 4; it is built entirely on it. If the estate is on Livewire 3, this package is not adoptable without a framework-wide major upgrade whose blast radius is the entire application, not this feature.
  2. Tailwind build coupling. Package views must be added to the app's content glob or the UI renders completely unstyled in production. This is a build-configuration dependency that fails silently and only at render time — the highest-probability "it worked yesterday" incident in the whole integration.

Technical risk

  • Supply-chain and bus-factor risk dominates. Zero stars, zero dependents, one maintainer, a single recent release. There is no community exercising edge cases, no issue history to mine for known defects, and no evidence of independent security review. For a component that mediates authenticated filesystem access, that is the single largest risk on the register — larger than any code-level concern.
  • Version matrix breadth. Claiming Laravel 10/11/12 (three majors) plus PHP 8.1+ plus Livewire ^4.0 is a wide support surface for a small team; expect gaps to surface at the edges of that matrix rather than the centre.
  • Security-sensitive defaults. uploads.mimes defaults to null, i.e. all MIME types accepted. root_resolver returning a value equal to the configured root, or null/'', grants full access — a resolver bug is a privilege escalation, not a display bug. The default route (GET /file-manager) must be confirmed to sit behind auth middleware and an application policy; route middleware is configurable, which means it is also misconfigurable.
  • The picker is a selection widget, not a validator. filter="images" is a UI affordance; the hidden input is client-controlled. Any team that treats it as a security boundary ships a vulnerability.
  • Trash semantics under multi-root scoping. With an array of roots, trash is shared and filtered by originalPath. If two users share a root, or if root scoping overlaps, deleted-item visibility becomes a cross-tenant information leak.
  • Media URL strategy is a security/performance fork. route proxies every asset through PHP (authorization per request, higher cost); storage is a direct URL (fast, CDN-able, but bypasses per-request authorization and breaks on private disks). auto hides the decision, which is worse for reasoning about production behaviour.

Key questions

  1. Which Livewire version is the target application on today, and is a Livewire 4 upgrade already planned or budgeted? What is its blast radius?
  2. Is the frontend Blade + Livewire, or Inertia/SPA? If the latter, this package is out on architecture, not on merit.
  3. What is the licence, and do we have explicit permission to fork and vendor? Given zero dependents, we should assume we may become the maintainer.
  4. What Tailwind version is in use (v3 tailwind.config.js vs v4 CSS-first configuration)? The documented content glob assumes v3-style config.
  5. Which disk(s) are in scope — public, private local, S3? If S3 or private local, media_url must be route or signed URLs, and that decision needs an owner.
  6. What is the authorization model beyond path confinement? There is no per-file ACL, no audit log, and no policy layer described. Is path scoping sufficient for the compliance posture of this product?
  7. Who audits this package on upgrade, and against what test suite? Is there a regression plan for PathGuard, upload handling and trash restore?
  8. What are the PHP upload_max_filesize / post_max_size / Livewire temporary-upload limits relative to uploads.max_size (default 50 MB)? Mismatches here produce user-facing failures that look like package bugs.

Integration Approach

Stack fit

Best case: Laravel 10.49+/11/12, PHP 8.1+, Livewire 4 already in use or approved, Tailwind compiled by the app, Blade-rendered forms. In that configuration the package is a near-drop-in and the picker alone justifies a pilot, because it replaces ad-hoc upload widgets across every form that attaches a file.

Poor fit: Inertia/React/Vue product, or an application still on Livewire 3 with no appetite for a major upgrade. In both cases, stop at the evaluation — the cost sits outside the feature.

Migration path from the legacy Next.js/React manager

The README's endpoint-by-endpoint mapping table is the migration plan's backbone, and it is unusually complete: api/files, api/files/tree, api/folders, api/rename, api/move, api/delete, api/upload, image/route.js, verify-token and the iframe postMessage each map to a Livewire method, a computed property, or MediaController.

Critically, the stored data does not move. Files remain on the same disk under the same paths; only the presentation and access layer change. That makes this one of the lower-risk migrations available. The residual work is decommissioning, not data movement: removing FILE_MANAGER_URL, the RS256 .pem keypair, the token-verify route, the CORS/proxy entries, and the iframe host page. Those decommissioning steps should be explicit tickets, not cleanup — stale JWT keys and a live external file service left reachable is a standing security finding.

Two configuration traps in the path: the defaults (root => conteudos, trash => apagados) are assumptions about the existing filesystem layout, not placeholders. If the legacy deployment used different roots, every path must be set via FILE_MANAGER_ROOT / FILE_MANAGER_TRASH or navigation will open onto an empty tree that looks like a broken install.

Compatibility

  • Multi-disk via Laravel's Filesystem is the right abstraction and S3-ready, but the media_url mode determines whether S3 actually works under authorization. Resolve this before enabling a non-public disk.
  • Translations are publishable PT/EN; a Portuguese-first project gets PT free, others ship EN. Publishing lang files creates local drift, so publish only if overriding.
  • Publishing views or assets shadows package updates — treat published copies as forked code requiring review on every package bump.
  • Middleware on file-manager.media and the full-page route must be checked explicitly, not assumed.

Sequencing

  1. Gate 1 — Livewire 4 decision. Confirm current version, upgrade cost, and owner. Do not start integration before this is answered.
  2. Gate 2 — deployment topology. Decide disk(s), media_url mode, and whether the full-page route is exposed at all or the component is embedded only.
  3. Scaffold in a non-production environment: publish config, read it end to end, wire the Tailwind content glob (or publish prebuilt CSS if the app does not compile Tailwind), run storage:link.
  4. Pilot the picker on one low-risk form. Replace a single ad-hoc upload widget, store the relative disk path on the model, keep validation in the FormRequest, exercise the file-manager-selected listener if live preview is needed.
  5. Harden the full-page surface: explicit auth + policy middleware, uploads.max_size and uploads.mimes set to allowlist rather than null, PHP upload limits aligned.
  6. Design root_resolver for tenancy before exposing the manager to more than one user population. Write tests for the escalation cases: resolver returning null, returning '', returning the config root, returning an array with overlapping roots, and traversal attempts above the resolved root.
  7. Schedule file-manager:prune-trash — daily, in the same change set as the route, not after.
  8. Decommission the legacy stack as explicit work: remove external service config, keys, proxy entries and the iframe host page.
  9. Vendor or mirror the package to a private source of truth, pin the exact version, and document the fork-and-patch procedure.

Operational Impact

Maintenance

Assume you will maintain this. Zero stars and zero dependents means no downstream bug-finding, no third-party patches, and a single point of failure in the maintainer. Practical posture: pin an exact version (not a caret range), mirror the repository internally, and review the diff of every upgrade as if it were internal code. The package's own documentation quality — README, a BACKOFFICE-INTEGRATION.md describing a real per-user scoping integration, and a published release — is materially better than its adoption metrics suggest, which lowers the cost of owning it.

The Tailwind content glob is a permanent maintenance liability: it lives in the application's build config but refers to a vendor path. A package upgrade that relocates views, or a build-config refactor that drops the line, produces an unstyled UI that no PHP test will catch. Add a smoke check to the release checklist.

Publishing views, lang files or assets creates a fork inside your own repo. Default to not publishing; publish only the config and only when defaults must change.

Support

No community, no SLA, no issue-tracker signal to triage against. Internal support means an internal owner with the authority to patch a vendored copy. Debugging information is favourable: it is Blade and Livewire inside your own application, so stack traces land in application logs and standard Livewire debugging applies — no black-box external service, no cross-origin token failures. Ramp-up for a developer already fluent in Blade and Livewire is a day; the genuinely hard part is understanding PathGuard and root_resolver semantics well enough to be confident in the tenancy boundary.

Scaling

Livewire's per-interaction round trip is the cost model. The directory tree lazy-loads per node and each navigation re-lists the directory, so behaviour degrades with directory cardinality, not with user count. Tens of files per folder is comfortable; thousands of files in one folder, or a deeply expanded tree, will produce slow renders and heavy listing calls. On S3 this is worse than on local disk because every render is API calls (and cost), not readdir.

media_url => route proxies every image and video byte through PHP: correct for private disks and per-request authorization, but it puts gallery traffic on the application tier. storage moves that to the web server or CDN at the cost of per-request authorization. Choose per disk, and revisit if a grid view with many thumbnails becomes a hot path.

Upload throughput is bounded by uploads.max_size defaulting to 50 MB, but the effective ceiling is whichever of upload_max_filesize, post_max_size and Livewire's temporary-upload configuration is lowest. Align all of them or users get opaque 413/422 responses.

Failure modes

  • Unstyled UI in production — Tailwind content glob missing or stale after a view path change. Silent, cosmetic, and the most likely first incident.
  • Unauthenticated file access — route middleware left at the package default rather than scoped behind auth plus a policy. Highest-severity, lowest-effort-to-prevent.
  • Privilege escalation via resolver — root_resolver returning null, '', or the config root grants full access. Needs an explicit test, because the failure is silent and looks like correct behaviour in a happy-path demo.
  • Unbounded trash growth — trash_retention_days is decorative without the scheduled command; apagados grows until the disk fills. The legacy implementation's 60-second-in-code-versus-30-days-in-docs bug is documented as fixed here, but only scheduled pruning makes the fix operational.
  • Broken media on private disks — media_url => storage against a non-public disk yields 403s or broken images, typically first noticed in production.
  • Trash restore collision — behaviour when the original path has been reoccupied or renamed is unspecified; test it before relying on restore.
  • Cross-tenant trash visibility — with array roots, trash is shared and filtered by originalPath; overlapping or shared roots leak deleted-file metadata between users.
  • Livewire 4 drift — an application-level Livewire upgrade or downgrade silently breaks the component; pin both sides.
  • Upload rejections users cannot diagnose — MIME allowlist (null by default, so permissive) combined with PHP limits produces generic validation errors.

Ramp-up

Low for the mainstream case: a Blade/Livewire developer can read the config, wire Tailwind, and drop the picker into a form in half a day, with the README's Next.js→Livewire mapping table serving as the mental model. Medium for the full-page experience, where route middleware, upload limits and media_url must be decided rather than defaulted. High for multi-tenant scoping: root_resolver plus PathGuard plus shared-trash filtering is the one area where a competent developer can ship a plausible-looking implementation with a real authorization hole, and it deserves a written design note, a reviewer who did not write it, and a test suite covering the escalation cases before it reaches any shared environment.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums