lara-zeus/bolt
Bolt is a form builder for Laravel that lets you define dynamic forms in code or store them in the database, then render them anywhere in your app with rich fields, validation, and simple customization.
Architecture fit. Bolt is a Laravel form-builder that sits on the Filament/Livewire stack: fluent form/field definitions, built-in validation, persisted submissions, Blade/Livewire rendering, and extensible custom field types. The TPM framing question is not "does it work" but "how much platform does it drag in." If our product is already a Laravel + Filament shop, Bolt is a bounded add to an existing mental model. If we are not, adopting Bolt materially means adopting Filament and Livewire — a platform decision that deserves its own ticket and sign-off, not a side effect of a "custom forms" request. Second fit question: are forms adjacent to the core product (CRM, HR ops, events, agency portals, per-tenant intake) or are forms the product? In the first case Bolt buys the boring 80% and compresses a multi-quarter obligation into a last-mile integration. In the second, it is a prototype scaffold, not a foundation.
Integration feasibility. Mechanically cheap: composer require lara-zeus/bolt, publish and run migrations, publish config/views as available, register the Filament plugin on the correct panel. The real feasibility work is a recon spike of one to two days that answers three things by reading source, not docs — the docs are thin. (1) Submission storage shape: normalized rows (form_id, field_id, value) versus a JSON blob per entry. This determines whether reporting, per-field deletion, and GDPR erasure are SQL or a PHP loop, and it is not reversible later. (2) What events fire on submission, and where — this dictates whether we can wrap cleanly or must poll. (3) The field base class, our extension point for custom field types. Deliverable from the spike: a one-page written finding plus a go/no-go, not a working demo.
Technical risk. The dominant risk is supply chain, not code. At ~243 stars and zero public dependents, plan for a single-maintainer, best-effort project with no SLA. The v5.0.7 changelog is entirely chores and Dependabot bumps, which is a healthy maintenance signal but not evidence of feature velocity; the listed last release date is in the future, so the release metadata itself is unreliable and must be re-verified against tags and commit cadence on GitHub before we quote dates anywhere. The tightest technical coupling is the supported Filament major — a form builder touches routing, auth, storage, mail, and the admin panel, which puts it on the critical path of every framework upgrade. Secondary risks: schema evolution when a live form is edited underneath existing submissions; XSS via user-authored labels/help text/option values rendered in both admin and public surfaces; abuse of public endpoints and file uploads with no built-in hardening we can assume; and tenant leakage if we are multi-tenant and rely on the package for scoping.
Key questions for the spike owner.
Stack fit and the honest cost. Confirmed Filament shop: proceed. Non-Filament shop: treat Filament adoption as a prerequisite workstream with its own estimate, and be prepared for the answer to be "not worth it for one form." The PM-level trade is real — MIT, self-hosted, no per-seat or per-submission fees, respondent data stays in our database — which is genuinely decisive in regulated or high-volume contexts where Typeform/Jotform/Tally routing is a non-starter.
Authoring model, decided explicitly. Bolt supports DB-authored definitions in the admin panel, and that self-serve capability is the actual product value. But sequence it: author the first form in PHP, committed and code-reviewed, so it appears in a diff and can be tested. Move to DB-authored definitions only for forms that genuinely need non-engineering changes, and only after the schema-evolution policy exists.
Migration path. Wrap, do not scatter. Form definitions live in dedicated classes (app/Forms/*), not controllers or Blade. Submissions flow through our own FormSubmissionService that calls into Bolt and re-emits our own FormSubmitted event; nothing outside that service imports a LaraZeus\Bolt\* class. Listeners on our event handle Slack, CRM, webhooks, audit rows. This is what makes "replace the vendor" a week rather than a quarter.
Compatibility policy. Pin the exact version ("lara-zeus/bolt": "5.0.7", not ^5.0). Record the supported Laravel/PHP/Livewire/Filament matrix in our upgrade docs. Add a Bolt smoke test to the Filament upgrade checklist. Treat forking as a budgeted contingency with a named owner, not a free option.
Sequencing.
PublicFormPage Livewire shell, then hardening (rate limiting per IP and per form, honeypot/captcha, size caps, upload validation and storage outside the public root).Ramp-up. Engineering needs Filament familiarity before day one. Ops needs a written rulebook: additive changes only, never retype or delete a field that has submissions, and a defined review step before a live form changes.
Maintenance. Low code churn expected, but non-zero obligation: a pinned version, a quarterly dependency review, an upgrade checklist entry, and one integration test per form — render returns 200, valid payload persists, invalid payload produces the expected error keys, submission event fires. Twenty minutes per form, catches most upgrade regressions.
Support. No vendor SLA and a thin community answer pool — we will be writing the Stack Overflow post. That means an internally named owner for the integration, and a documented "work down from the rendered output" debug path: stale published views in resources/views/vendor/, validation bag and transaction boundary for silent failures, panel registration for a missing admin resource.
Scaling. Two cliffs. The first is reporting: if entries are JSON, "all submissions where budget > 50k grouped by month" is a PHP loop over every row — fine at hundreds, catastrophic at scale. Decide per form which are capture-only and which need a maintained projection table. The second is write-path contention on public forms; downstream processing (notifications, CRM sync, webhooks) belongs on a queue so a burst doesn't block the request.
Failure modes to design against.
{!! !!}, wire: attribute injection, and JS handoff.Pilot metrics that make the business case defensible. Track form-change ticket volume, cycle time from request to live form, and engineering hours reclaimed. That is the backlog-reduction argument — a self-serve capability that shows up in a quarterly review as reclaimed capacity, not as a feature bullet.
How can I help you explore Laravel packages today?