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

Bootstrap Bundle Laravel Package

smirik/bootstrap-bundle

Symfony bundle that integrates Bootstrap into Symfony applications, providing Twig helpers, form themes, and templates for common UI components. It simplifies building responsive forms, menus, alerts, and navigation with consistent Bootstrap markup while reducing repetitive frontend boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the reality check. This is a Symfony bundle (Smirik\BootstrapBundle), not a Laravel package. You cannot composer require it into a Laravel app — the service-container extension, bundle registration in AppKernel.php, and Twig form-theme conventions have no counterpart in Laravel. If you're on a modern Symfony (5/6/7) app, the framework already ships bootstrap_5_layout.html.twig, so you don't need it either.

What you actually do with this package day-to-day: treat it as reference material. It contains two reusable things worth reading: the Bootstrap asset include and the form theme. You port them.

Read in this order:

  1. Resources/public/ — the vendored Bootstrap CSS/JS. Check the version first (this predates BS4/5; expect BS2/3 class names like control-group, has-error, help-block).
  2. Resources/views/Form/ (form_div_layout.html.twig overrides) — the actual value: how each form_row/form_widget/form_errors block is wrapped.
  3. Resources/views/layout.html.twig — the block naming and asset include pattern.
  4. DependencyInjection/ and Resources/config/ — to see whether anything is configurable (usually not much).

First use case — port the form theme to Blade. The Symfony block looks roughly like:

{% block form_row %}
  <div class="form-group{% if errors|length %} has-error{% endif %}">
    {{ form_label(form) }}
    {{ form_widget(form) }}
    {{ form_errors(form) }}
  </div>
{% endblock %}

The Laravel equivalent is a Blade component in resources/views/components/form/field.blade.php:

@props(['label' => null, 'name', 'error' => null])
<div class="mb-3 {{ $error ? 'has-error' : '' }}">
  @if($label)
    <label for="{{ $name }}" class="form-label">{{ $label }}</label>
  @endif
  {{ $slot }}
  @error($name)
    <span class="form-text text-danger">{{ $message }}</span>
  @enderror
</div>

That is the whole package's value, reproduced in your own repo in under an hour — and under your own review.

Implementation Patterns

1. Asset loading — skip the bundle's approach, use Vite. The bundle's job is to emit <link>/<script> for Bootstrap. In Laravel that's your build pipeline:

// resources/js/app.js
import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';

Then reference it once in the base layout: @vite(['resources/js/app.js']). The bundle's Resources/public convention is the Symfony Assetic-era equivalent — don't try to reproduce it.

2. Form field rendering as components. The most useful pattern to carry over is the "wrap label + widget + errors in a fixed container" convention. Build one <x-form.field> wrapper plus thin per-type components (<x-form.input>, <x-form.select>, <x-form.checkbox>). Keep the markup in one place so a Bootstrap major upgrade is a single-file change.

3. Error display convention. The bundle consistently treats errors as a sibling of the input (not nested), with an has-error wrapper class. In Blade/BS5 the equivalent is:

<input class="form-control @error('email') is-invalid @enderror" ...>
@error('email')<div class="invalid-feedback">{{ $message }}</div>@enderror

Establish this convention once; the bundle's discipline here is worth borrowing even if the class names aren't.

4. Layout/block convention. The bundle ships a base layout you extend with {% block body %}. The Blade analogue is a layouts/app.blade.php with @yield('content') or $slot. If you're already standardizing layouts, this is where the reference is most useful — compare your block structure to what the bundle chose (it's a reasonable, if old, starting point for admin screens).

5. If you're genuinely on Symfony. Don't port it — register the built-in theme instead:

twig:
    form_themes:
        - 'bootstrap_5_layout.html.twig'

That's first-party, maintained, version-locked with the framework. The bundle is essentially this same idea, frozen in 2013.

Gotchas and Tips

  • Bootstrap version drift is the biggest trap. This bundle targets Bootstrap 2.x/3.x. Class names have changed (control-group → form-group → mb-3, help-block → form-text, has-error → is-invalid). Copying markup verbatim into a BS5 app will produce visually broken but functionally "passing" forms — the failure mode is cosmetic, so tests won't catch it.
  • form_errors is a separate block from form_widget. In a partial port, it's easy to render both form_errors(form) inside form_widget and again inside form_row, producing duplicated error messages. If you port, keep the error rendering in exactly one place.
  • Form theme registration ordering matters. In Symfony, later twig.form.resources entries override earlier ones — overriding only a few blocks lets the rest fall through to a base theme you may not expect. If porting to Symfony, check what form_div_layout.html.twig is still rendering for untouched blocks.
  • Assets publishing is fragile. assets:install --symlink and assetic:dump fail silently on hardened CI (symlink restrictions), Windows developer machines, and Docker volumes. If you find yourself debugging "why are assets not updating," the answer is usually a stale symlink — assets:install --symlink --relative or a hard copy avoids it. Don't bother resurrecting Assetic; it's dead on both Laravel and modern Symfony alike.
  • Check the DI extension for real config. Most of these small bundles expose almost nothing configurable — the Extension class and Resources/config/*.yml will tell you in 30 seconds whether there's a knob worth looking at. Usually there isn't.
  • The layout may not use your asset pipeline. If the bundle's layout.html.twig references paths under Resources/public, you'll need assets:install before anything renders — but once ported to Blade/Vite, this whole class of gotcha disappears. That's the argument for porting rather than depending.
  • Extension points are effectively none. There's no service API, no events, no hooks. The only "extension" is overriding Twig blocks — which means your customizations are fragile against any upstream change. Vendoring the templates as your own code is strictly better than depending on them.

Bottom line for a Laravel team: you will never require this. Extract the form theme (one file), translate class names to your Bootstrap major, and move on. The day-to-day leverage is small and one-time, but the form-theme pattern is worth a look before you write your own.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons