awcodes/matinee
Matinée is an OEmbed and video field for Filament panels and form builders. It stores video data as JSON, supports YouTube and Vimeo out of the box, allows custom providers, and can force a preview to display.
Architecture fit. Matinée is a Filament form field, not a media library. It occupies one narrow seam in the application: the authoring surface of the admin panel, plus exactly one model column. It registers no routes, ships no controllers, no storage disk abstraction, no queue jobs, and — critically — appears to perform no outbound HTTP at render time, resolving URLs by parsing the host against a provider contract and assembling an embed_url with http_build_query(). That makes it an authoring-time dependency with a blast radius confined to the panel and a single JSON column. Your public-facing site consumes only the stored JSON via a Blade component you are free to replace with your own markup. This is the favorable shape for a TPM: the package never becomes a runtime hard dependency of customer traffic.
Integration feasibility. High, but conditional on two prerequisites that must be scheduled as tasks, not footnotes:
@source '../../../../vendor/awcodes/matinee/resources/**/*.blade.php'. The README flags this as [!IMPORTANT]. It is the single most common place implementations stall, because teams without an existing custom theme must build one first.After those, the field is a one-liner (Matinee::make('video')), the model needs a single cast ('video' => 'array'), and front-end work can be parallelized against a documented, stable JSON payload (url, embed_url, width, height, responsive, options).
Technical risk. The risks here are supply-chain and version-coupling, not runtime correctness.
| Risk | Assessment | Mitigation |
|---|---|---|
| Bus factor | Single maintainer (awcodes), 22 stars, 0 dependents |
Reputable Filament-ecosystem author, but you are effectively the only consumer. MIT + ~a few hundred lines of code means a fork is cheap; budget 1–2 days as a standing escape hatch. |
| Filament major coupling | 1.x→F3, 2.x→F4, 3.x→F4 and F5 | v3.x spanning two Filament majors on one line is a genuine win — it de-risks your next Filament upgrade. Verify this holds through F6. |
| Latent platform bug | v3.1.1 fixed an mb_trim() call requiring PHP 8.4 against a declared ^8.2 constraint, caught pre-tag |
Evidence of active CI and that the codebase is thin enough for platform bugs to hide. Pin your PHP floor; review patch diffs. |
| Layout regression history | v3.1.2 fixed fixed-size embeds silently flipping back to responsive, undefined array key on missing dimensions, and full-width stretching of non-responsive embeds |
Recent — check your Filament/PHP combination against ≥3.1.2 and add a stored-payload regression test. |
| Theme coupling | Requires custom theme + @source glob |
Explicit prerequisite task with its own estimate. |
| Documentation drift | README trimmed to a landing page pointing at docs.aw.codes |
External doc site is a link-rot and availability risk; snapshot the docs into your internal runbook. |
Key questions for the maintainer / a timeboxed spike.
Stack fit. Adopt only if the target admin is Filament 4 or 5. There is no adaptation path for Nova, Backpack, or hand-rolled Laravel admin — do not attempt one; a hand-rolled URL field plus a Blade partial is less work than bending this package. No database engine, queue, cache, or hosting constraints apply.
Migration path. Two scenarios with very different cost:
json column, add the cast, drop the field into the form. No backfill, no dual-write, no cutover. Estimate 0.5 day, plus theme setup if none exists.varchar URL columns, or rows where a youtube_url string and separate start_time integer already exist, require a one-way transform into the JSON shape. Realistically: write a backfill command that constructs {url, embed_url, width, height, responsive, options} per row, run it in dry-run mode against a production snapshot, verify a sample of 20–50 rows render correctly through <x-matinee::embed>, then keep the old column read-only for one release cycle before dropping. Estimate 3–5 days including verification and a rollback plan (retain the source column until the new render path is signed off in production).Compatibility. Pin explicitly. Filament 4/5 → Matinée ^3.1.2; PHP floor ^8.2 is declared but 3.1.x history argues for testing on your exact PHP minor. Do not use a floating * constraint given 0 dependents — you are the only canary.
Sequencing. Order matters here because the theme prerequisite gates everything visual:
<x-matinee::embed>, then decide whether to keep it or substitute your own markup for consent gating.nocookie option to the provider defaults and wrap embeds in your consent manager. Video embeds are a known GDPR/CCPA friction point; bake this in rather than retrofitting.Total for greenfield: ~2–3 days including compliance. Existing-data migration: add 3–4 days.
Maintenance. Expect near-zero routine maintenance and a low but non-zero upgrade tax. The package tracks Filament majors, so your real maintenance trigger is a Filament upgrade, not a Matinée release. Because 3.x supports two Filament majors simultaneously, that tax is currently deferred. Assign a named owner (a single developer is sufficient) and a review policy: read every patch diff before merging — one to two files, minutes of effort. Watch for the pattern seen in 3.1.1/3.1.2 where a fix ships a day apart from the release that introduced the issue; that argues for a short soak period on staging before production.
Support. No vendor SLA, no commercial support, community-only issue tracker. For an internal admin tool used by a bounded set of editors, that is usually acceptable. Establish an internal runbook covering: how to add a new provider, what the stored JSON shape is, how to debug a blank embed, and where the fork lives if you need it. Two translations (Italian, Spanish) already ship — if your editors work in other locales, budget a small i18n contribution or an override.
Scaling. Effectively a non-issue on the write side: form submissions are rare, human-paced, and involve no external calls or queues. Two scaling considerations on the read side:
nocookie flag is your lever; consider lazy-loading (loading="lazy") in your wrapper.Failure modes and responses.
| Failure | Symptom | Response |
|---|---|---|
| Provider removed from config after data written | Stored row no longer resolves; field likely cannot rehydrate | Treat stored embed_url as source of truth at render time, never re-resolve from url on the public site. Confirm behavior in the spike. |
| Malformed / unsupported URL | Field rejects input at authoring time | Acceptable — fails loudly at the right moment, in front of an editor, not a visitor. |
Missing width/height in stored payload |
Was an undefined array key warning + 0-size render; fixed in 3.1.2 |
Pin ≥3.1.2 and add a fixture test asserting 16:9 fallback. |
| Fixed-size embed flips to responsive | Resolved in 3.1.2 | Pin ≥3.1.2; regression test on round-trip edit-and-save. |
| Maintainer abandons repo | No further Filament compatibility | Fork (MIT), or replace with a ~100-line custom Filament field — the surface is small enough that this is a real option, not a bluff. |
| Theme CSS not rebuilt after upgrade | Field renders unstyled or partially styled | Fold @source recompile into the standard Filament upgrade checklist. |
Ramp-up. Very low. One developer, half a day to a day, with the README plus a short internal note. The concepts an engineer must hold are three: the JSON column contract, the provider interface (getId, getDomains, getOptions, convertUrl), and the theme @source requirement. No new infrastructure, no new runtime, no new mental model beyond Filament forms they already use.
Build-vs-buy verdict. At 22 stars, 0 dependents, and a single maintainer, the honest framing is: you are adopting a convenience wrapper worth perhaps 1–2 developer-days of saved effort, in exchange for a small ongoing dependency and a documented fork option. That trade is favorable for a greenfield Filament 4/5 panel where the field replaces bespoke code. It is not favorable if you are on Filament 3 (take 1.x as legacy or skip), if you have complex existing video data (the backfill dominates the value), or if your compliance posture requires full control over embed markup from day one — in which case take the stored-JSON idea and the provider interface, and implement the field yourself.
How can I help you explore Laravel packages today?