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

Bootforms Laravel Package

typicms/bootforms

BootForms for Laravel simplifies building Bootstrap-styled forms with a fluent API, automatic validation error display, model binding, and sensible defaults. Generate clean form markup quickly while reducing repetitive HTML and boilerplate.

Deep Wiki
Context7

Getting Started

Install and wire it up

composer require typicms/bootforms

Package discovery should register the service provider. If you are on an older Laravel or have discovery disabled, add TypiCMS\BootForms\BootFormsServiceProvider to config/app.php manually. Check composer.json for the supported Laravel range before committing — this is a small, single-maintainer package (13 stars) maintained primarily for TypiCMS' own admin UI, so the version constraints track what TypiCMS itself needs.

You also need Bootstrap 5 CSS and JS loaded in the layout that renders the form. BootForms emits Bootstrap 5 class names (mb-3, form-control, form-select, form-check, is-invalid, etc.) but does not ship the CSS. Without it you get correct semantics and broken visuals, which is the most common "it's not working" report.

Where to look first

  1. README.md — the API surface is small and fully documented there; read it end to end, it takes five minutes.
  2. src/FormBuilder.php / src/Form.php — the fluent builder and the renderer. This is where every field type and modifier lives, and it is the real documentation.
  3. resources/views/ — the Blade partials that actually render each control. If you need to change markup, this is your extension point.
  4. config/bootforms.php (publish with php artisan vendor:publish --tag=bootforms-config if present) — usually just error-display and layout defaults.

First use case

Take one hand-written form in your app — an edit screen is ideal — and convert it. The shape is:

{!! BootForm::open()->action(route('posts.update', $post))->put() !!}
    {!! BootForm::text('title', 'Post title') !!}
    {!! BootForm::textarea('body') !!}
    {!! BootForm::select('status', 'Status', ['draft' => 'Draft', 'live' => 'Live']) !!}
    {!! BootForm::submit('Save') !!}
{!! BootForm::close() !!}

Then delete the equivalent markup from the Blade file. If the form looks right and old input repopulates on a validation failure, the package is doing its job.

Implementation Patterns

Open/close with explicit verbs. Use ->action() plus ->method() / ->put() / ->patch() / ->delete() so the builder emits the hidden _method field for you. Don't hand-write @method next to a BootForm opener — you'll get two.

{!! BootForm::open()->action('/posts')->post() !!}
{!! BootForm::open()->action(route('posts.update', $post))->put()->multipart() !!}

->multipart() is the one people forget; without it file uploads silently arrive empty.

Model binding beats manual ->value(). Bind the model once and let the builder read attributes and old input:

{!! BootForm::open()->action(...)->put()->model($post) !!}
    {!! BootForm::text('title') !!}
{!! BootForm::close() !!}

Then only reach for ->value() on fields that aren't model attributes (search filters, computed defaults). Mixing the two — binding a model and setting ->value() everywhere — makes it ambiguous which wins when old input is present.

Layout modes are set on the opener, not per field. ->horizontal() (with label-width options) and ->inline() apply to the whole form. Pick one per form; switching mid-form produces misaligned columns that are tedious to debug.

Modifiers chain, and they're the whole ergonomic win:

{!! BootForm::text('slug')
    ->placeholder('auto-generated')
    ->help('Leave blank to derive from the title.')
    ->required()
    ->readonly($post->exists) !!}

->required(), ->disabled(), ->readonly(), ->help(), ->placeholder(), ->label() and ->value() all return the field, so order rarely matters. ->required() sets the HTML attribute only — it is not a validation rule. Always pair it with a FormRequest rule; BootForms renders errors but does not enforce anything.

Errors come from the shared error bag. The builder reads $errors for the field name and applies is-invalid / renders invalid-feedback. Two consequences:

  • Wrap the form in the normal @if($errors->any()) alert block if you want a summary; the per-field messages appear automatically.
  • Named error bags (used with FormRequest::errorBag) need the bag wired through the builder or the field stays clean. If you use them, verify against src/Form.php — this is the area most likely to need a one-line customisation.

Selects, checkboxes and radios. Select options take an associative array and support ->select($value) for the default. Checkbox and radio groups take name, label, options and render Bootstrap 5 form-check markup. For a single boolean, BootForm::checkbox('published', 'Published') in the classic API is a lone toggle, not a group — check which signature your installed version uses in src/FormBuilder.php before assuming.

Reuse via partials or Blade components. Wrap common field clusters (address block, SEO metadata block) in resources/views/partials/fields/*.blade.php and @include them. Pass the builder in if you need it, but the simpler pattern is to let each partial call BootForm:: statically — it's a facade-style singleton, so no wiring is required.

Custom field types: use macros. Rather than forking, register a macro in a service provider if the package supports it (FormBuilder::macro(...)); otherwise extend the builder class and swap the container binding. For a package this size, prefer macros and custom Blade partials over a fork — you want to stay on upstream releases.

Gotchas and Tips

Everything is raw output. You must render with {!! !!}, not {{ }}. The builder escapes attribute values, but the returned HTML is trusted markup — never pass unescaped user input into label, help, or option text expecting another round of escaping.

Bootstrap 5 renamed the form classes. If you're porting templates from the original BootForms (Bootstrap 3) or from Bootstrap 4 projects: form-group is gone (use mb-3), form-control-file and custom-control custom-checkbox are gone (use form-check), and .row/.col-form-label grids behave differently. Any old CSS or JS you wrote against custom-control will quietly stop applying. This rename is the single biggest source of "the classes look almost right" bugs.

Old input vs. model binding precedence. After a failed validation, old input wins over the model attribute — that's what you want, but it surprises people who set ->value() explicitly and find it ignored on redisplay. If a value must never be repopulated (e.g. a password field), confirm the builder treats password inputs specially or zero it out server-side.

File inputs cannot be repopulated. Browsers forbid it. Don't design a flow that depends on the filename surviving a validation round-trip.

Arrays in select/checkbox fields need explicit value casting. For multiple selects, old input arrives as an array; if your default is an Eloquent collection, cast to an array before passing it as the default value or nothing appears selected.

Validation is entirely your job. BootForms is a renderer. You still need a FormRequest, rules, and authorisation. The ->required() attribute is a hint to the browser, not a guard.

Debugging rendered markup. Instead of reading a 200-line Blade output in devtools, dump the generated string: call the builder, dd((string) $field) or echo it into a <pre>. When a class or an is-invalid is missing, the answer is almost always (a) the field name doesn't match the error key, or (b) $errors isn't shared into the view — check HandleExceptions/ShareErrorsFromSession middleware is active for that route.

Small package, thin release history. With 13 stars and a single organisational maintainer, expect the README to be the only documentation and expect issues to go unanswered. Pin an exact version in composer.json, keep a short internal note on which BootForms version maps to which Bootstrap 5 minor, and treat major upgrades as a manual review of src/Form.php rather than a composer update you trust. If you need a form builder with a larger community, Laravel Collective's HTML package or plain Blade components are the alternatives to weigh — BootForms' advantage is genuinely the concise chainable syntax and Bootstrap 5 markup done for you.

Extension points worth knowing: published views (change markup globally without touching call sites), builder macros (add project-specific field types), and the service provider binding (swap in a subclass for app-wide behaviour). Prefer them in that order.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource