digital-creative/nova-filepond
Nova Filepond is a Laravel Nova field that integrates the FilePond upload library, giving you drag-and-drop, image previews, and smooth asynchronous file uploads inside your Nova admin panels with minimal setup.
dcasia/nova-filepond is a Laravel Nova field that swaps Nova's stock file/image uploader for FilePond's drag-and-drop UI — previews, progress indicators, single/multiple modes, and client-side validation options. It is an admin-UX accelerator, not a platform and not a DAM. The correct TPM framing is a small buy-over-build decision for internal back-office upload surfaces, where the real risk sits in storage semantics, path handling, and load-endpoint authorization — not in the package's code volume.
Architecture fit. Strong, but conditional on three things holding simultaneously:
public with storage:link, or S3 with temporaryUrl reads.The primary architectural contract: the field writes relative paths into the model column (or an array of paths under ->multiple()) — never URLs. URL resolution belongs to the application, via a model accessor/cast or a Nova display field. That is genuine application work and must be planned up front rather than discovered in review. A secondary contract: ->prunable() fires on actual model delete, so soft-delete-heavy schemas need an observer or forceDeleted hook instead. The v1.0.6 release is a narrow patch — it corrects the filename returned by the Load Controller when a path is set (previews show photo.jpg rather than avatars/photo.jpg) — and adds no capability. It is hygiene, not strategy.
Integration feasibility. High for a Composer-managed Nova app. Install, optional config publish, and Nova auto-registers assets with no npm/mix build step; a field is live in a few lines. The published config (default disk, temp path, load/store route names, route middleware) is the sanctioned override surface. Beyond it, the only extension path is subclassing the field and overriding load()/store() — there are no events to hook, which means any customization becomes a permanent in-house subclass to maintain. Two items reliably consume engineering time: the explicit disk (omitting ->disk('public') inherits filesystems.default, usually local, landing files in storage/app where the browser cannot reach them) and the load endpoint that hydrates existing files on the edit screen, where a 401/403 from a guard mismatch or expired signed URL is the usual cause of "broken previews."
Technical risk. Low for this specific release — no breaking changes, deprecations, or new features are indicated. Residual risk concentrates in five places:
| Risk | Severity | Mitigation |
|---|---|---|
| Nova/Laravel/PHP/FilePond version compatibility not restated in release notes | Medium–High (fails late, as confusing frontend errors) | Verify Composer constraints and asset auto-registration on the target Nova version before committing; record the support matrix in-repo |
Client-side-only validation (maxFileSize in bytes, not KB, and advisory; REST endpoint can be called directly) |
High | Duplicate every limit in server-side validation rules — mandatory, not optional |
| Load Controller authorization, signed-URL behavior, and disk/path isolation, including tenancy boundaries | High | Explicit review of the load route middleware and guard; subclass if our authz model exceeds what ships |
Custom path / load-controller behavior and downstream consumers parsing the name field |
Medium | End-to-end test of default and custom path flows; audit any consumer of the name attribute |
| Community maintenance: 55 stars, 0 dependents, single-maintainer pattern, last release 2024-01-31 | Medium (strategic, not immediate) | Named owner, pinned Composer version, pre-agreed fork capacity |
One non-obvious upgrade hazard worth flagging to engineering: v1.0.6 makes existing displayUsing() basename shims and directory-stripping load controllers redundant. Left in place they can double-strip filenames, so the upgrade is not purely additive for teams that patched around the bug. Shim removal should be an explicit, reviewed change, not incidental cleanup in an unrelated PR.
Key questions.
Stack fit. Adopt for Nova admin surfaces where the team wants FilePond UX without owning frontend upload code: avatars, document attachments, single- and multi-image galleries, media fields on content resources. Do not adopt as the basis for a public upload pipeline, asset transformation/rendition, compliance- or SLA-bound media, or an enterprise DAM — stretching the field into those roles converts a cheap accelerator into a bespoke platform resting on a single-maintainer dependency.
Migration path. For v1.0.5-and-earlier users, v1.0.6 is a drop-in patch: no config or migration changes indicated. For new adoption it is a greenfield field addition, not a migration. Either way the shape is identical: pin the version in Composer, install or upgrade in a non-production environment, then validate default and custom path flows end to end. Where the team previously worked around the filename bug, sequence shim removal as its own reviewed change.
Compatibility. Verify Composer constraints against the application's Laravel, Nova, PHP, and FilePond asset versions before committing — this is the highest-value pre-work item, because a Nova major-version mismatch surfaces late as confusing frontend failures rather than a clean install error. Confirm asset auto-registration works on the target Nova version and that load/store route middleware matches the guard Nova authenticates against.
Sequencing.
public vs. S3-with-temporaryUrl, and whether php artisan storage:link is required per environment.Scope the pilot deliberately by risk: single-image fields on a public disk with default paths are wave one; multi-file galleries, custom load/store controllers, and tenancy-scoped authorization are wave two and require their own regression pass.
Maintenance. Low per-release cost, but a non-zero standing cost. The package is feature-complete for our purposes and effectively in maintenance mode; expect infrequent releases. The real standing cost is the bus factor: one maintainer, 55 stars, zero dependents, no release since 2024-01-31. Plan for the scenario where a Nova major ships and the package does not follow — that is a fork-and-patch exercise owned by whoever is named accountable. Budget one small engineering ticket for adoption plus a QA pass against the multi-week cost of a bespoke Nova upload field; that comparison is the whole business case.
Support. No vendor, no SLA, no procurement. Internal support burden is limited to two recurring issues: the explicit-disk misconfiguration (files written to storage/app, unreachable from the browser) and load-endpoint 401/403s from guard or signed-URL mismatch. Both are diagnosable in minutes with a runbook. Everything else — client-side validation limits, filename display, prunable behavior on soft deletes — should be documented once as known constraints so each new engineer does not rediscover them.
Scaling. Adequate for admin upload volume. The package inherits Nova's storage conventions, so throughput scaling is a function of the underlying disk (local vs. S3), not the field. Two limits to respect: chunked/large-video uploads should be treated as unproven until exercised against our storage backend and web-server body-size/timeout limits; and the temp upload directory needs scheduled pruning at every scale, since it grows with traffic and never self-cleans.
Failure modes. Four to instrument and watch for one release cycle:
storage:link — uploads succeed silently but files are unreachable. Verify with a download test per environment.Rollback is low-cost: pin the prior Composer version and the field reverts. That low exit cost is the strongest argument for treating this as a contained, reversible bet.
Ramp-up. Fast for any engineer already fluent in Nova fields — a few lines of configuration and an afternoon of staging QA. The non-obvious learning is concentrated in three decisions (disk choice, URL resolution, load-controller auth), so encode those in the repo as an ADR rather than tribal knowledge. Allocate roughly one small ticket for adoption, one QA pass, and a short runbook entry covering the four failure modes above.
How can I help you explore Laravel packages today?