tomatophp/tomato-forms
Tomato Forms is a form builder for TomatoPHP and Filament that lets you create dynamic, database-backed forms and manage submissions from your admin panel, with reusable field components so you can add custom forms to any Laravel app without boilerplate.
Architecture fit. The package is a Filament v3 plugin that ships migrations, config, two admin resources, and a form → fields → answers-in-user-meta data model. That model is the actual product value: admins author field definitions in a panel, and answers land as key/value rows against the user record instead of new schema columns. It fits an existing Laravel + Filament admin surface that needs config-driven, admin-authored data capture. It does not fit as a system of record — key/value meta is a rendering and capture layer, not a reporting or billing substrate.
Integration feasibility. The install path is short and standard (composer require, publish config and migrations, migrate, register the plugin in the panel provider). The surface is small enough to read end-to-end in an afternoon. The single unknown that gates the whole plan: is there a non-panel render/submit path, or is this admin-only? If admin-only, we own the Blade renderer and the submit endpoint, which is where most of the integration effort actually lives.
Technical risk. Ordered by severity:
filament/filament constraint in the package's composer.json before installing.{!! !!} in package views is a persistent vector.Key questions to answer before committing.
filament/filament version constraint, and does the plugin boot on our current major?Stack fit. Strong if we are already on Laravel + Filament v3 inside the TomatoPHP ecosystem. Weak if we are on Filament v4, on a non-Filament front end, or if the forms are customer-facing — in each of those cases the fork effort approaches a small in-house build.
Migration path. Treat this as fork-and-own under MIT, not as a dependency. Concretely:
"tomatophp/tomato-forms": "1.1.19"), commit the lock file, and plan to vendor into an org namespace. A floating constraint is a future broken build given the dormant upstream.Compatibility. Verify the Filament constraint against our major before any install work. Pin PHP and Laravel versions in the fork's composer.json. Budget for one Filament-major bump as recurring, not one-time, maintenance.
Sequencing (days, not weeks).
FormRepository / SubmissionRepository interfaces between app code and package tables. This is the highest-leverage decision — it survives a storage swap.forms.{slug}.{field}); never key on field ID.match/@switch with an @includeIf fallback so custom types are partials, not package edits.migrate:fresh and diff in PRs.Maintenance. Upstream is effectively dormant; we own patching, security review, and Filament compatibility permanently. The codebase is small enough that this is realistic, but it is a standing line item, not a one-off. Keep the fork diff auditable so a future maintainer can reason about it.
Support. Internal, admin-authored users only at first. No external SLA, no customer-facing exposure. Publish authoring conventions as part of rollout: never rename a field key (add new, hide old), never delete a field without archiving, never put PII or file uploads in a form until those paths are audited.
Scaling. Low-traffic internal capture is fine. The scaling bottleneck is read-back: aggregating answers across users from a key/value meta store is slow and awkward, and every reporting, billing, compliance, or deletion-rights requirement pushes toward a typed submissions table. Plan the storage decision before volume makes it expensive.
Failure modes and named mitigations.
$request->all().{{ }} everywhere, audit package views for {!! !!}.Ramp-up. One Laravel developer, half a day to spike, one to two days to a production-safe internal deployment with the repository seam, namespaced keys, and server-side revalidation. Add roughly a day for the orphan sweep and seam tests. No dedicated SME required — the surface is small enough to read fully, which is also why fork-and-own is the credible endgame rather than a straight dependency. Keep this off the critical path: nothing revenue-critical, customer-facing, or PII-bearing should sequence behind a package with zero dependents and a single maintainer.
How can I help you explore Laravel packages today?