amjadiqbal/filament-record-pdf
Filament Record PDF adds PDF export to Filament resources, letting you generate and download a PDF for any Eloquent record from the admin panel. Configure Blade templates and options to customize the output, then trigger it via a table or header action.
This is a first public release (v1.0.0), so the evaluation is a greenfield adoption decision rather than an upgrade decision. The package is a Filament-native action set that generates server-side PDFs for individual records, built on spatie/laravel-pdf with dompdf as the default driver. Architecture fit is good for teams already standardising on Filament 4/5 admin panels: it slots into the existing action/notification/policy patterns rather than introducing a parallel rendering pipeline or a sidecar service. The value proposition is consolidation — five actions (Preview, Download, Email, Save, BulkDownload) plus a shared option surface (pdfView, pdfData, pdfFilename, pdfFormat, pdfLandscape, pdfDriver, modifyPdfUsing, pdfAbility, authorizePdfUsing) replaces what is typically bespoke, duplicated PDF controller code in every Filament project.
The design shows product-level thinking rather than a thin wrapper. Preview renders once and serves a cached, signed, user-bound URL for 10 minutes with a download button reusing the same artefact — a correct response to the fact that dompdf rendering is the expensive operation. Bulk downloads above a configurable threshold (default 25) move to the queue with a database notification and expiring signed link, which protects the web tier from the most obvious denial-of-service-by-accident vector. Per-record policy checks (viewPdf/downloadPdf/emailPdf/savePdf with fallback to view/update) mean authorization is not an afterthought bolted on later.
Integration feasibility is high but bounded by version gates: PHP 8.2–8.5, Laravel 12/13, Filament 4/5. Teams on Filament 3 or Laravel 11 are excluded. The dependency floor on spatie/laravel-pdf 2.14.0 and dompdf ≥3.1.6 is reasonable and explicitly justified — the release notes call out six 2026 dompdf advisories including an SVG local file read, which is exactly the kind of disclosure a TPM wants to see in a v1.0.0.
Technical risk clusters in four areas:
[a-z0-9-] plus .pdf, save directories forced relative and free of ./..) and user-bound signed URLs are the right controls. The residual question is whether URL access re-verifies session authorization or relies on signature plus embedded user id alone — signature-plus-binding is generally sound, but it needs confirmation against the code, not the release notes.Test coverage for a v1.0.0 is above the norm: 67 Pest tests across a PHP 8.2–8.5 × Laravel 12/13 × Filament 4/5 matrix, lowest-supported dependency pins exercised, PHPStan level 5, Pint, plus a 44-check headless-Chrome UI test on freshly installed apps in light and dark themes covering preview, download, email, save, path traversal, policies, inline and queued bulk, and header actions. PHPStan level 5 is mid-tier for security-sensitive path handling; worth tracking whether it rises.
Key questions before adoption: what is the license and is it compatible with our distribution model? Is the 10-minute preview cache TTL configurable, and how does the cache key isolate users and tenants? What are the queue connection, retry, and failure semantics for bulk jobs — and does the user get notified on failure, or only success? Is there rate limiting on EmailPdfAction and BulkDownloadPdfAction to prevent an authenticated user from using the app as a mail relay? What is the mail attachment size ceiling, and does the package guard against oversized dompdf output? Does the built-in view and email template support localization? What is the release cadence and deprecation policy, and will Filament 4 support persist once 5 becomes dominant?
Stack fit is narrow and clean: Laravel 12/13 applications running Filament 4/5 panels. There is no meaningful fit outside that envelope, and no partial-adoption story for non-Filament surfaces — the actions are Filament actions, not generic service classes. Where the stack matches, the package is essentially drop-in: composer require amjadiqbal/filament-record-pdf, register actions on resources or pages, scaffold views with php artisan make:record-pdf-view.
Migration path is replacement, not coexistence. Existing bespoke PDF controllers, DomPDF facades, and hand-rolled download routes should be retired resource by resource as their Filament equivalents land. Two compatibility checks gate the composer step: whether the project already depends on spatie/laravel-pdf (version alignment) and whether any other package pins dompdf below 3.1.6 (a hard conflict the security posture cannot absorb). Optional integrations — spatie/laravel-medialibrary collections and queue-backed notifications — pull their own prerequisites.
Sequencing should be staged to match risk:
overwrite(false) accumulates files indefinitely. Decide medialibrary versus plain disk before wiring, because switching later means data migration.Compatibility is bidirectional and must be re-validated at each Filament minor bump. Treat the package as a pinned dependency (~1.0) and re-run the pilot resource after Filament upgrades rather than assuming the matrix covers your exact version combination.
Maintenance burden is low in steady state and spiky at Filament upgrade boundaries. The package is a thin composition layer, so most incidents trace back to Filament or dompdf rather than to this code. The dominant structural risk is single-maintainer continuity; mitigate with version pinning, a documented fork contingency, and a habit of reading release notes before upgrading Filament. PHPStan level 5 and the advisory-aware dependency floor are good signals, but neither substitutes for an internal code review of the path-handling and signed-URL logic before production use.
Support load will be driven by document fidelity, not by the package. Users will report "the PDF looks wrong" and the root cause will usually be dompdf's CSS subset or a missing font. The mitigation is organisational: publish an internal standard for PDF Blade views (table-based layout, no flexbox/grid, no JavaScript, embedded fonts), keep one reference template, and require review of each new view. If a resource genuinely needs modern CSS or chart rendering, switch that action to a Browsershot/Gotenberg/Cloudflare driver via pdfDriver() — but that decision pulls headless Chrome or an external rendering service into the infrastructure estate, which is a real cost increase and should be approved deliberately rather than by default.
Scaling characteristics are favourable with caveats. dompdf is CPU- and memory-bound in PHP, with no external service to saturate; capacity planning reduces to worker count and PHP memory limits. The preview render-once-then-cache pattern removes the most common amplification (users clicking preview repeatedly), and the queued bulk threshold protects the request/response path. Storage is the under-managed dimension: saved PDFs with overwrite(false) plus transient bulk ZIPs grow without bound, so retention, cleanup jobs, and disk quota alerts are required from day one. Queue depth becomes a user-visible SLO for bulk exports; define an expected "your export is ready" latency and alert on breach.
Failure modes to instrument explicitly: dompdf exhausting memory on records with large line-item counts or embedded images; cache eviction invalidating a preview URL mid-session; signed-link expiry during a slow bulk job; queue worker downtime causing silent non-delivery of both the ZIP and the notification; mail rejection from attachment size or deliverability; disk full on save or bulk paths; misconfigured medialibrary collection; and, if a non-default driver is adopted, unavailability of the Chrome or Gotenberg endpoint. Each needs a defined user-facing behaviour — the current release notes describe the happy path thoroughly but do not describe degradation.
Ramp-up is short for anyone already fluent in Filament: an experienced developer can wire the actions for a resource in under a day. The realistic per-resource estimate is one to two days once view design, policy decisions, filename conventions, and stakeholder review of the rendered document are included. First-resource onboarding should absorb the learning curve — infrastructure checks, driver choice, template standards, retention policy — so subsequent resources are largely duplication. Total cost of ownership is attractive relative to maintaining bespoke PDF code per resource, provided the team accepts the Filament version coupling and the single-maintainer dependency as known, accepted risks.
Basis of assessment: release notes for v1.0.0 only. No source review, license confirmation, or documentation audit beyond the linked README was performed; findings on authorization internals and configuration defaults should be validated against the code before a production commitment.
How can I help you explore Laravel packages today?