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

Laravel Livewire Forms Laravel Package

wotz/laravel-livewire-forms

A Laravel package for building and managing forms with Livewire, helping you wire up form components, validation, and stateful UI without repetitive boilerplate. Streamlines common form workflows so you can focus on your app's logic.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and verify compatibility first. The package is a thin Livewire form abstraction, so its constraints are your constraints:

composer require wotzebra/laravel-livewire-forms:^5.1

v5.1.0 adds PHP 8.5 / Laravel 13 support, so the floor has moved. Confirm the Livewire major it targets in composer.json (livewire/livewire: ^3.0 is the safe assumption for a 2026 release) and the PHP/Laravel floor before writing code. Pin to ^5.1 deliberately: the 5.x line is now the maintained line, and you want the Laravel 13 compatibility commit rather than an arbitrary earlier 5.x.

Where to look first, in order:

  1. The Laravel Boost guidelines shipped in v5.1.0. This is the single biggest change for day-to-day work. The package now ships AI guidelines and "skills" consumed by Laravel Boost, so after php artisan boost:install your AI assistant gets package-authored, version-matched guidance about the form API. Read that file yourself too — it's typically the most concise, current description of the API surface (base class name, rules(), messages(), lifecycle hooks) and it's maintained by the author rather than inferred.
  2. README.md — the author's own happy path. Small packages like this usually have exactly one supported workflow; find it and stay inside it.
  3. src/ — look for the base form class (typically Form, BaseForm, or a HasForm trait). That file is the entire API surface: property hydration, rules(), messages(), submit(), and any lifecycle hooks. src/ wins over the Boost guidelines whenever they disagree — AI guidelines can lag a release.
  4. config/ — if a config file is publishable, it usually controls validation message namespacing, view paths, or auto-binding behaviour.

First use case: a single-resource create/edit form (a Post, a Profile, a support ticket). Do not start with multi-step wizards or nested repeaters — those are where thin abstractions break, and you want to learn the package's serialization rules on something small.

php artisan boost:install                              # pull in the packaged AI guidelines
php artisan vendor:publish --tag=livewire-forms-config # if it exists

Build one form, submit it, and assert it with Livewire::test() before committing to the pattern across the app.

Implementation Patterns

Form object as a public property. The standard shape is a plain PHP class holding your fields, exposed on the component as a public property so Livewire can hydrate it each request:

class ContactForm extends Form   // exact base class name: check src/
{
    public string $name = '';
    public string $email = '';
    public string $message = '';

    public function rules(): array
    {
        return [
            'name'    => ['required', 'string', 'max:120'],
            'email'   => ['required', 'email'],
            'message' => ['required', 'string', 'min:20'],
        ];
    }
}

class ContactPage extends Component
{
    public ContactForm $form;

    public function mount(): void
    {
        $this->form = new ContactForm();
    }

    public function submit()
    {
        $this->form->validate();

        Contact::create($this->form->toArray());

        $this->form->reset();
        $this->dispatch('contact-sent');
    }
}

Keep validation in the form, orchestration in the component. The value of a form package is co-locating rules with fields so the same form can be reused by an HTTP controller, a Livewire component, and a seeder. If you start putting rules in the component, you've paid the dependency cost for nothing.

Let Boost carry the conventions. Rather than re-teaching your team (or your AI assistant) the form API in every prompt, rely on the packaged skills to scaffold new forms. The practical workflow: ask the assistant to generate a form extending the package base class, then diff its output against src/. Anything the assistant invents that isn't in src/ — a save() helper, a different hook name — is hallucination, not API.

Model binding pattern. For edit screens, the usual idiom is a fill(Model $m) / toArray() pair on the form class. Bind in mount(), and save by mapping back explicitly rather than mass-assigning — mass assignment from a form object is how you accidentally expose is_admin.

Reuse via a Blade partial. Render the form fields in resources/views/livewire/forms/contact.blade.php and @include it wherever needed. This is the main practical payoff: one field definition, used in a modal, a full page, and a test.

Compose with Livewire actions. Emit events on success ($this->dispatch('saved')) and let the parent page close the modal or refresh a table, rather than having the form class reach into UI concerns.

Nested data / repeaters. If the package supports array fields, treat them as an add-on: public array $items = [['sku' => '', 'qty' => 1]] with dot-notation rules (items.*.sku). Verify hydration survives a re-render before building a whole UI on it.

Gotchas and Tips

  • Public properties must be serializable. No closures, no Request instances, no raw Eloquent models inside the form object on a subsequent request — Livewire round-trips public state through the payload. Store IDs or scalars and re-resolve in mount() or the action.
  • wire:model timing is the #1 source of "it doesn't validate" bugs. wire:model (deferred) won't update on blur; wire:model.live fires every keystroke and will hammer your updated() hooks. Use .blur or .live.debounce.500ms for text, .live for selects/checkboxes.
  • File uploads require WithFileUploads on the component. The form object cannot make uploads work on its own; the trait must be on the Livewire component, and the temp file property must live where Livewire can see it (usually on the form object, but the trait on the component).
  • Double submits. Livewire forms get submitted twice by impatient users. Wrap submit() in a $this->lock guard or disable the button with wire:loading.attr="disabled" plus wire:target="submit".
  • reset() vs. $this->reset(). If the form class provides its own reset(), it may not reset validation errors. Call the package's reset and $this->resetValidation() (or confirm the package does it) — otherwise stale error bags persist after a successful save.
  • Validation message customisation. Look for a messages() method on the form class or a validation.php translation key the package namespaces. If neither exists, pass messages via the validate($rules, $messages) call and keep them out of the form class.
  • Extension points are thin. Likely hooks: beforeSave/afterSave, or an overridable submit(). If you need something the package doesn't expose, subclass the base form rather than forking — subclassing survives composer update, forking does not.
  • Boost guidelines are a snapshot, not a contract. They ship with the release, so they describe that version's API — good. But they're prose, so they can be aspirational or stale relative to a bug fix. When behaviour surprises you, read src/ and the changelog, not the guidelines. Also re-run boost:install after upgrading the package, or you'll be coding against v5.0 guidance on a v5.1 install.
  • PHP 8.5 / Laravel 13 support is now explicit — but only on 5.1+. If your app is on Laravel 13 and you pin an older 5.x, expect resolution failures or subtle breakage. Conversely, if you're stuck on PHP 8.2/Laravel 11, the v5.1 constraint bump may exclude you; check composer.json before assuming the upgrade is free.
  • Small-maintainer risk, now lower. v5.1.0 shows outside contributors and Copilot-assisted maintenance, which is a healthy sign — but the package is still small and single-maintainer-led. Pin an exact minor version in composer.json, and keep your form classes free of package-specific logic beyond the base class and rules(). If the package disappears, swapping to a hand-rolled form object should be a one-file change per form.
  • Debugging hydration failures. When a form mysteriously resets to defaults, dump the Livewire payload (Livewire::test(...)->payload()) and check whether a typed property is receiving a mismatched type — a string property fed null from an empty input is the classic failure, and PHP 8 typed properties will throw rather than coerce.
  • Test the round trip, not just the unit. Livewire::test(ContactPage::class)->set('form.email', 'bad')->call('submit')->assertHasErrors('form.email') — note the form. prefix, which trips people up when copying rules from a controller.
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