van-ons/filament-attachment-library
Filament package for easy attachment uploading and browsing. Install via Composer, run the install command to set up migrations and assets, then extend your custom Filament theme's Tailwind config to render the templates correctly.
Architecture fit. The package is a Filament plugin with a thin UI layer over a companion library (van-ons/laravel-attachment-library), which owns the domain model (Attachment, HasAttachments trait, attachmentCollection() morph relation) and image transformation via Glide. This is a sensible separation: the Filament package supplies the AttachmentField form component, an attachment browser, and Alpine/Livewire assets, while persistence and image processing remain in the Laravel package. For a TPM, the practical consequence is that adopting this is a two-package commitment — the Filament plugin is not self-contained, and the model-layer contract (trait, relationship naming, ATTACHMENTS_DISK env var, glide.php/attachment-library.php config) comes from the sibling package and must be reasoned about separately. It is not a generic media library; it is a Filament-native attachment picker with a morph-pivot storage model, plus an optional column-based mode for single attachments.
Integration feasibility. Straightforward on a greenfield Filament panel: Composer require, filament-attachment-library:install, register the plugin in the panel provider, add the field to a form schema, optionally add the trait to a model. The non-trivial step is theme integration — the package's Blade templates ship Tailwind classes that must be included via @source in a custom Filament theme, which in turn must be registered on the panel (and, in Vite projects, registered via ->viteTheme(...)). That means any adopting app must already have (or must create) a custom theme pipeline; apps relying solely on Filament's default compiled CSS cannot render the package correctly. This is the single largest integration constraint and it is a build-pipeline change, not just a config change.
Technical risk. Moderate, concentrated in four areas. (1) Custom theme requirement — introduces a permanent build step and a failure mode where styles silently break after a Filament major upgrade or a Vite config change. (2) Asset publication — Alpine components are shipped as a committed resources/dist bundle, republished via Filament's filament:upgrade hook; apps without that hook must run filament:assets manually, which is an easy-to-miss deploy step and a source of "works locally, broken in staging" bugs. (3) Maturity/community signal — 11 stars, 0 dependents, single-vendor stewardship (Van Ons). The changelog shows real production usage and disciplined hygiene (Dependabot, security-relevant fixes such as path/value sanitization and MIME enforcement on dropped files), which is reassuring, but bus factor is low and the ecosystem signal is weak. (4) Livewire interaction complexity — the v1→v2 history is largely a sequence of Livewire fixes (multiple browsers causing Livewire issues, wire:key on lazy components, null-state handling in the browser). This suggests the UI layer is stateful and has a track record of edge-case bugs; expect to test modal/browser behavior under nested forms and repeaters specifically.
Key questions.
ATTACHMENTS_DISK)? The README explicitly advises a disk with no other files — do we have that isolation, and does it work with S3/compatible object storage plus Glide's cache path?attachments() relationship (multi-collection galleries) or only single-column attachments? The former implies a schema addition and a data-lifecycle story (orphan cleanup, deletion cascades).laravel-attachment-library-image + Glide means we are committing to a specific image-delivery path; does that conflict with an existing CDN/image-optimizer?Stack fit. Best fit is a Filament v3/v4 admin panel on Laravel 10/11+ with an existing Vite build and a custom theme already in place. Fit degrades to "adds work" if the team has no custom theme (theme creation becomes a prerequisite task) and to "poor fit" if the application is headless/API-first, since the value is delivered almost entirely through Filament form components and Blade rendering. The package explicitly depends on Tailwind being compiled by the host app, so it cannot be a drop-in for panels using only Filament's prebuilt CSS.
Migration path. Treat adoption as a feature slice, not an infrastructure swap:
@source line, register both theme and plugin, and confirm upload + browse + render end to end with the default public disk.relationship() collection) against a real resource we actually need.HasAttachments trait on existing models (a schema migration: pivot table + backfill if we are replacing an existing media solution).There is no in-place migration from another media library; any replacement of existing upload fields requires a data backfill into the new attachment tables and a period of dual-read.
Compatibility. Two axes to pin explicitly: Filament major version (v1 → v2 of this package is a breaking line; the changelog shows a maintained v1 branch receiving backports, which is a positive sign but also means version choice matters) and Tailwind/Vite configuration (custom theme registration differs for Vite projects per the README). Also pin the companion laravel-attachment-library version, since the field's behavior and the Blade component come from it. Lock both in composer.json with caret constraints and record the exact combination validated in the spike.
Sequencing.
<x-laravel-attachment-library-image> usage.filament:assets).Maintenance. Ongoing cost is threefold: (a) the custom theme is now a maintained artifact — every Filament upgrade requires regenerating/validating it and re-checking the @source path, which is tied to the vendor directory layout; (b) the committed JS bundle must be republished on composer updates (automatic only if the filament:upgrade hook is present — verify, and otherwise add php artisan filament:assets to the deploy script); (c) two packages to track for releases, not one. Low bus factor means we should assume we may need to fork; MIT licensing makes that viable, and the codebase is small enough (Filament field + browser + Blade templates + Alpine) that a fork is a realistic contingency rather than a fantasy.
Support. No commercial support; support channel is GitHub issues. Vendor (Van Ons) is an established Dutch agency, and the release cadence plus Dependabot activity indicate active stewardship. The presence of SECURITY.md, an UPGRADING.md, versioned docs, and a documented compatibility matrix is above average for a package at this size and materially lowers support risk. Recent security-adjacent fixes (path/value sanitization, MIME enforcement on drops) are worth noting to security review as evidence of responsiveness — and as a reason to stay current on patch releases rather than pinning and forgetting.
Scaling. Upload/browse is admin-plane traffic, so request volume is low; the scaling concern is storage and image transformation, not application load. Glide resizing introduces a derivative cache that grows with image variety and must be sized, monitored, and invalidated on replace (the package added replace/move operations in v2, so invalidation paths exist). Attachment counts per model and total disk usage need a retention story: nothing in the README describes garbage collection for orphaned attachments, so plan for a scheduled cleanup job and a "delete file when attachment deleted" policy. If attachments are served from a public disk, consider whether public-by-URL is acceptable for the content being uploaded, or whether signed URLs are required — this is a policy decision the package does not make for you.
Failure modes. Ranked by likelihood:
filament:assets in deploy.ATTACHMENTS_DISK set per environment.wire:key, null currentPath). Mitigation: exercise the field inside repeaters, nested forms, and multi-panel setups during the spike.Ramp-up. Developer ramp-up is short — the README's quick start is genuinely one command plus a theme edit, and the included skills/attachment-field agent skill lowers the cost of getting a new contributor to a working field. The real ramp-up cost is organizational: someone must own the theme pipeline, the deploy step, and the storage/retention policy. Estimate: half a day for one developer to reach a working spike, one to two days to productionize including theme and deploy changes, and a standing line item in the Filament upgrade checklist. Given the low star count and zero dependents, the honest TPM framing is: technically a good fit with a small, well-scoped integration cost; the risk is stewardship and the theme coupling, not the code. Approve for a spike, gate production adoption on the compatibility matrix check, the storage decision, and a documented fork contingency.
How can I help you explore Laravel packages today?