Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Form Laravel Package

laraflow/form

Laraflow Form is a Laravel package that streamlines building, rendering, and managing forms. It offers a fluent API, reusable components, validation support, and Blade integration to help developers create maintainable forms faster.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and verify before you build on it

composer require laraflow/form

The package is now at 0.2.0 (pre-1.0, coming from 0.1.4). Treat the first 30 minutes as a due-diligence pass rather than a normal install:

  1. Recognise the versioning. You are on a 0.x package, so semver gives you nothing: a 0.1.x → 0.2.0 bump is allowed to contain breaking changes, and the 0.2.0 changelog is a single line ("inline style issue fixed", PR #57). PR numbers in the 50s on a package with 16 stars means many small unannounced iterations — assume the changelog is terse, not complete. Diff 0.1.4...0.2.0 yourself on GitHub before upgrading an existing install, and pin the exact version you tested.
  2. Check the constraint resolution. Run composer why laraflow/form and confirm which Illuminate versions it actually allows. If it pulls a loose constraint (^9|^10|^11), pin the exact package version in composer.json immediately — a patch release is unlikely to be covered by community bug reports.
  3. Confirm auto-discovery. Look for LaraFlow\Form\FormServiceProvider in vendor/laraflow/form/composer.json under extra.laravel.providers. If it is not listed, register it manually in bootstrap/providers.php (Laravel 11+) or config/app.php.
  4. Read src/ before the README. With a package this small the whole source is probably a handful of classes — a Form facade/builder, a FormBuilder/Field class, and Blade views for the Bootstrap markup. Skim them. You need to know whether it renders Blade partials (so you can publish/override them) or concatenates HTML strings (so you cannot). The 0.2.0 fix is worth locating specifically: find where that inline style is emitted. If it lives in a PHP string rather than a Blade view, view publishing will not reach it.
  5. Publish whatever is publishable. php artisan vendor:publish --provider="LaraFlow\Form\FormServiceProvider" and inspect config/form.php and any resources/views/vendor/laraflow output. Overriding the Blade views is your primary escape hatch for Bootstrap-version mismatches and markup you dislike.

First use case: replace hand-written Bootstrap markup in one CRUD form

Pick your most boilerplate-heavy form — typically a create.blade.php with 8–12 fields, each wrapped in a <div class="form-group"> with a <label>, an is-invalid error class, and old() repopulation. Rewrite that single form with the package and compare line count and markup output. If the generated markup matches your Bootstrap version and handles old() + $errors correctly, roll it out; if not, stop there — you have lost an hour, not a sprint.

A typical call site looks like:

{{ Form::open(['route' => 'users.store']) }}
    {{ Form::text('name', null, ['label' => 'Full name', 'required' => true]) }}
    {{ Form::email('email', old('email')) }}
    {{ Form::select('role', $roles, null, ['placeholder' => 'Choose a role']) }}
    {{ Form::submit('Save', ['class' => 'btn btn-primary']) }}
{{ Form::close() }}

Implementation Patterns

Wrap it in your own Blade components — do not call the facade in 40 views

The single highest-leverage pattern with any form builder is a thin local abstraction layer. Create resources/views/components/field.blade.php (or an App\Support\Form wrapper class) that delegates to the package, and call that from your views. When the package is abandoned or you upgrade Bootstrap, you change one file instead of every form. It also lets you standardise things the package won't know about: your error-bag convention, your label translations, your wire:model / Alpine bindings, and stripping any inline style attributes the package emits.

Form object / definition class for large forms

For anything beyond ~10 fields, move the schema out of Blade into a PHP class:

class UserForm
{
    public function __construct(private array $roles) {}

    public function build($model = null): array
    {
        return [
            'name'  => ['type' => 'text', 'label' => 'Full name', 'required' => true],
            'email' => ['type' => 'email'],
            'role'  => ['type' => 'select', 'options' => $this->roles],
        ];
    }
}

Then loop in Blade and hand each entry to the package's field renderer. This gives you one place for validation rules ↔ field mapping, reuse across create/edit, and testability without rendering HTML.

Edit forms: rely on model binding, not manual values

Pass the Eloquent model as the second argument (or call Form::model($user, [...]) if the package supports it — check src/ for a model()/bind() method). For packages without binding, standardise on old('field', $model->field ?? null) everywhere so a failed validation round-trip and a fresh edit page behave identically. Inconsistency here is the #1 source of "my edit form wiped the data" bugs.

Validation errors: pick one convention and enforce it

Determine what the package does with $errors — does it accept an error key per field, read the default error bag automatically, or do nothing? If it does nothing, wrap every field:

{{ Form::text('email', null, ['label' => 'Email']) }}
@error('email') <div class="invalid-feedback d-block">{{ $message }}</div> @enderror

Use a named error bag ($errors->store) and pass it explicitly if you have multiple forms on one page — otherwise two forms with a name field will light up simultaneously.

Compose with JS/Alpine for dynamic fields

Pre-render a hidden template block and clone it client-side, or use the package inside an Alpine x-for loop with indexed names (items[__INDEX__][sku]). If you clone server-rendered markup, beware that the package has already burned in the field id — you must rewrite id/for/name attributes in JS. Safer: render the field schema as JSON with @json() and generate markup with the same class names on the client.

Integration points worth wiring up in a real app

  • Resource controllers: create/edit share a _form.blade.php partial that takes $model; only the action URL and method differ (Form::open(['route' => [...], 'method' => 'PUT'])).
  • Livewire: if you use Livewire, a server-rendered form builder is mostly redundant — use wire:model on plain inputs and reserve the package for non-Livewire, full-page forms. Mixing both in one view fights over old()/hydration.
  • Tests: assert on stable attributes you control (custom id/data-testid), not on the package's generated classes. Add one smoke test that GET /users/create returns 200 and contains each field name — that catches breaking upgrades cheaply, including a silent 0.1.4 → 0.2.0 markup change.
  • File uploads: any form containing a file field needs 'files' => true (or the equivalent enctype="multipart/form-data") on open. Verify the package sets this when a file field is present; if not, set it explicitly.

Gotchas and Tips

Inline styles are baked into the markup. The entire 0.2.0 release is an inline-style fix, which tells you the package emits style="..." attributes from PHP rather than deferring to your stylesheet. That is a coupling problem: inline styles beat your CSS on specificity, they may not be reachable via published views, and they will reappear whenever the package decides a new one is needed. After installing, run a generated form through grep 'style=' in the rendered output and note what you'd have to override. Prefer a wrapper component that strips them, or a small CSS layer with !important scoped to the package's class prefix.

Bootstrap version coupling is the biggest risk. The package is "based bootstrap form components", so it hardcodes Bootstrap classes. The Bootstrap 4 → 5 transition removed .form-group, .custom-select, .custom-control, and .input-group-append. Inspect the generated HTML against your Bootstrap version on day one. Fix via published view overrides, or add a small CSS compatibility shim rather than forking the package.

CSRF and method spoofing. Confirm open() emits @csrf and that a method option produces <input type="hidden" name="_method">. If it doesn't, add them yourself — a silently missing CSRF token in development (where it may be excluded) and a 419 in production is a classic trap. Check VerifyCsrfToken exceptions too.

Nested and array field names break auto-generated IDs. A name like user[email] produces an invalid id="user[email]", so <label for> no longer associates — an accessibility and click-target regression. If the package doesn't sanitise, pass explicit id and label options, or sanitise with Str::slug(str_replace(['[', ']'], ['_', ''], $name)).

Name collision with laravelcollective/html. Both expose a Form facade / Form alias. If you have both installed (common during a migration), the alias resolution is order-dependent and fails at runtime with confusing method-missing errors. Alias explicitly in config/app.php or bootstrap/app.php, and never let both render on the same page.

Escaping. Labels and help text are usually printed raw or escaped depending on the package. If you need HTML in a label (e.g. a tooltip icon), verify it's allowed; conversely, never pass unescaped user data as a label. Audit src/ for {!! !!} in the package views — that's a one-line audit with a real security consequence.

old() behaviour after a redirect. Repopulation only works if the field name matches the validation rule key exactly, including array notation. A mismatch (role_id field vs role rule) means empty fields after a failed save with no error message shown. Test the failure path, not just the happy path — fill the form with invalid data in devtools and submit.

Low bus factor, and the changelog won't save you. With 16 stars, zero dependents, and a single maintainer, assume no one will fix your bug report — and assume the release notes are a headline, not a description. The 0.2.0 notes say only "inline style issue fixed"; PR #57 is the real documentation. Mitigations, in order of preference: (a) constrain to the exact tested release, "laraflow/form": "0.2.0", and never accept a ^0.2 range on a 0.x package; (b) publish and override views so most cosmetic fixes live in your repo; (c) if the package is load-bearing, fork it and point Composer at your fork with a vcs repository — a 500-line form builder is cheap to own. When upgrading, read the GitHub compare link rather than the release body.

Extension points. Look for a macro/extend mechanism or a resolvable custom-field registry in src/. If there is one, register your domain-specific fields (money input with currency prefix, slug-generating text, address autocomplete) as macros in a service provider so they're available everywhere. If there isn't, that absence is itself a reason to prefer a wrapper-component layer.

Performance is a non-issue, but loops aren't free. Form builders are called at render time and can't be cached; rendering 500 rows × 6 fields through a facade is measurably slower than a @foreach of raw inputs. For repeated field groups (line items, permissions matrices), use plain Blade or a partial, and reserve the package for ordinary forms.

Debugging tip that saves the most time: render the form and diff the generated HTML against a hand-written Bootstrap reference form. Every divergence (missing is-invalid, wrong column classes, duplicated id, stray style attributes) is a future bug and is visible in ten seconds in devtools. Do this once at adoption, and again after any upgrade — especially a 0.x minor like this one, where a one-line changelog may understate the diff.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo