defstudio/wired-tables
defstudio/wired-tables is a Laravel Livewire package for building interactive data tables. It helps you render sortable, searchable, and paginated tables with customizable columns and a clean, component-driven API. Designed to keep table logic in PHP while staying easy to extend and style.
composer require defstudio/wired-tables and confirm you're on Livewire 3 (v2.x of this package tracks the Livewire 3 line; the 0.x line is the Livewire 2 era). Laravel 10/11/12 and PHP 8.2+ — including the newly added PHP 8.4 support — are the target matrix.php artisan vendor:publish --tag="wired-tables-config"
php artisan vendor:publish --tag="wired-tables-views" # only if you intend to override markup
Then make sure Livewire's @livewireStyles / @livewireScripts (or the Vite livewire.js import) are in your layout — the inline-edit behaviour is Alpine-driven and silently does nothing without them.config/wired-tables.php (defaults for pagination, theme, editable behaviour), the WiredTable base class (lifecycle hooks, query handling), and the Column classes (the actual API surface you'll spend your day in).columns() method; each column is a fluent object (->searchable(), ->sortable(), ->editable(), ->format(...)). Keep the component thin — it's a view model, not a service.protected function query(): Builder
{
return User::query()->whereBelongsTo(auth()->user()->team));
}
This is the single most important pattern: every subsequent feature (search, sort, pagination, inline save) operates on whatever this returns, so tenancy and soft-delete rules belong here and nowhere else.->editable();is_admin) with an explicit check rather than trusting the UI to hide them.App\Tables\BaseTable with your house style (rows-per-page, date formatting, action column, empty state), then every concrete table is 20 lines. Push column definitions into small factory methods (StatusColumn::make()) once you have more than three tables doing the same thing.@can in Blade. The Blade directive hides the control; the table class must still authorize the save. Pattern: a canEdit(User $record, string $column): bool method on the table class consulted by both the cell renderer and the save handler.Livewire::test(UsersTable::class) and assert on assertSee, assertSet, and call('...') for sort/filter transitions. Don't test the package's Alpine behaviour — test that your authorization, validation rules, and query scoping hold.v0.2.43...v2.0.0) and the README/CHANGELOG on the tag before upgrading. Assume namespace moves, column API signature changes, and a Livewire 2→3 break; budget a real upgrade branch rather than a composer update.composer.json ("^2.0") and read the diff once per minor.$fillable is potentially writable from a table cell. Audit $fillable/$guarded on every model you put behind an editable table; consider a dedicated $fillable for the table or explicit per-column assignment.wire:model.debounce/->deferLoading()-style behaviour and check your query count — a table with relationship columns will N+1 hard. Eager-load relationships used in columns in the query() method.How can I help you explore Laravel packages today?