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

Ui Laravel Package

bastinald/ui

Bastinald/UI is a Laravel package providing reusable Blade and Livewire UI components for building clean, responsive interfaces. It reduces repetitive markup and helps developers ship consistent, polished frontends faster, so you can focus on application logic instead of boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

bastinald/ui is a scaffold-and-forget starter kit: it drops a Livewire 2 + Bootstrap 5 shell (layout, navbar, auth screens, flash messages) plus a CRUD generator into a fresh Laravel app. It is not a runtime dependency you compose against — it's a code generator you run once and then own the output.

Minimal path:

composer require bastinald/ui
php artisan ui:install          # layout, navbar, auth Livewire components, routes
npm install && npm run dev      # compiles Bootstrap 5 SCSS/JS

Run php artisan list | grep ui immediately after install — the exact command set shifts between tagged releases, and the generator names are the only thing you'll interact with day-to-day.

Your first end-to-end use case should be the one the package exists for: a table you can list, search, create, edit and delete without writing a controller.

php artisan make:model Post -m
# add columns (title:string, body:text, published:boolean) to the migration
php artisan migrate
php artisan ui:crud Post

Where to look first, in this order:

  1. routes/web.php — the installer rewrites it; this is the map of what got generated.
  2. resources/views/layouts/app.blade.php — the @livewireStyles / @livewireScripts / navbar contract every generated view extends.
  3. app/Http/Livewire/ — auth components and, after ui:crud, your CRUD component.
  4. resources/views/livewire/ — the Blade the component renders.

If auth is all you need, ui:install alone gets you login, register, forgot/reset password as Livewire components, wired to the auth middleware — no Breeze, Jetstream, or Fortify involved.

Implementation Patterns

Treat the install as a one-shot on a clean app. The installer writes into routes/web.php, resources/js/app.js, resources/sass/app.scss and resources/views/. Commit or branch first. On an app that already has auth scaffolding, it produces collisions rather than merges.

Model-first, then generate. The CRUD generator infers form fields from the model's table schema, so the migration must be written and run before you invoke it. The workflow that holds up:

php artisan make:model Invoice -m
# edit migration -> columns
php artisan migrate
php artisan ui:crud Invoice

Expect a single fat component, not a controller/resource pair. Generated CRUD components typically hold list state, a modal-backed create/edit form, validation rules, and delete in one class. That's the pattern to lean into rather than fight:

class Posts extends Component
{
    public $post;          // model being edited
    public $showModal = false;
    public $search = '';

    protected $rules = [
        'post.title' => 'required|string|max:255',
        'post.body'  => 'required|string',
    ];

    public function render()
    {
        return view('livewire.posts', [
            'posts' => Post::query()
                ->when($this->search, fn ($q) => $q->where('title', 'like', "%{$this->search}%"))
                ->latest()
                ->paginate(10),
        ])->layout('layouts.app');
    }

    public function save()
    {
        $this->validate();
        $this->post->save();
        $this->showModal = false;
        $this->dispatchBrowserEvent('flash', ['message' => 'Saved']);
    }
}

Prune the generated field list. The generator emits inputs for every column it finds. Immediately delete id, created_at, updated_at, email_verified_at, remember_token, and any user_id from both the rules and the Blade form; set those server-side in save() instead.

Customize in the generated files, not by extending. There is no plugin surface worth using. Want a filter dropdown or bulk actions? Edit the generated component and view directly. That's the intended usage and the reason the package can be low-maintenance.

Reuse the layout for hand-written pages. The fastest way to add a non-CRUD screen is a one-line Livewire component returning a view with ->layout('layouts.app'). You inherit the navbar, auth links and flash handling for free.

Auth pages are yours to edit. app/Http/Livewire/Auth/*.php after install. Add fields (terms acceptance, username) by editing the component's rules and the Blade view — no vendor publish dance needed.

Gotchas and Tips

Livewire 2 only. The generated markup and event style ($this->emit, wire:model.defer, @livewireScripts) predate Livewire 3. Pin livewire/livewire:^2.0 or budget a rewrite of every generated component — .defer is gone and events became dispatch().

Bootstrap pagination is not automatic. Add Paginator::useBootstrapFive() in AppServiceProvider::boot(), or every generated list renders Tailwind pagination markup inside your Bootstrap table.

Modals need the Bootstrap JS bundle. The generated "show modal" behavior relies on the compiled bootstrap JS being present in resources/js/app.js (bundle build, not the standalone build — dropdowns and modals need Popper). Symptom: $dispatchBrowserEvent('show-modal') fires, console is clean, nothing appears.

Mix vs Vite. This package assumes Laravel Mix (resources/sass/app.scss, npm run dev). On Laravel 9+/10 with Vite, you must port the SCSS entry and add the @vite directive to layouts/app.blade.php manually; @livewireStyles/@livewireScripts stay where they are.

unique rules break on update. The generated rule validates against the table, so saving an edited record with an unchanged unique field fails. Add Rule::unique('posts','slug')->ignore($this->post->id) yourself — the generator doesn't.

Password reset silently fails. The auth scaffold is complete but mail isn't configured. Set MAIL_MAILER=log in local to verify the flow before blaming the component.

Debugging generated Livewire. Use window.livewire in the console and the network tab's /livewire/message payloads. If a click does nothing, the overwhelmingly common causes are a missing wire:key in a @foreach and a public property whose name doesn't match the Blade binding.

Don't mix with Breeze/Jetstream. Both define /login, /register and an auth middleware contract; running them alongside this package produces duplicate route errors. Pick one.

Maturity assessment. 115 stars, low activity, era-specific dependencies. Value it as a generator, not an ecosystem: after ui:install and your first ui:crud, the code in your repo is self-contained and the package can be removed from composer.json. That's the safest way to adopt it — copy the output, delete the dependency, and keep the Bootstrap 5 + Livewire architecture it establishes.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core