TL;DR
- Upstream
rappasoft/laravel-livewire-tablesmarked Livewire 4 supportwontfix, so I forked it. - The fork now targets Laravel 13 (keeps 12), runs on Livewire 4, and drops Livewire 3.
- Tests moved to Pest 4 (old PHPUnit classes still run via interop), with a Testbench workbench demo app.
- Takeaway: when an upstream says no, a fork is fine — but only if you bring the test harness with you.
Why fork at all
I lean on this package across projects: sortable, searchable, filterable tables for Livewire. The problem: upstream declined Livewire 4 support (wontfix) and hadn’t shipped Laravel 13. I didn’t want to be stuck on Livewire 3 forever, so I started a v4 line in my fork at cleaniquecoders/laravel-livewire-tables.
A fork is like renovating a rented house you’ve decided to buy — worth it only if you’re committed to maintaining it. I am, so the roadmap lives in GitHub milestones M1–M8.
What landed today
| Milestone | Change |
|---|---|
| M1 | Laravel 13 + Livewire 4 support; drop Livewire 3 |
| M2 | Migrate test suite to Pest 4 + Testbench workbench demo |
| M3 | Upstream bug-fix cluster + regression tests |
| CI | Replace L10/L11 workflows with a v4 matrix |
| — | Pint formatting pass under the upgraded toolchain |
The constraint matrix
The dependency floor moved up. Here’s the before/after:
| Before | After | |
|---|---|---|
| PHP | 8.1+ | 8.2+ |
| Laravel | 10 / 11 | 12 / 13 |
| Livewire | 3 | 4 (3 dropped) |
| Tests | PHPUnit | Pest 4 (PHPUnit interop) |
CI now runs the cross-product so a regression on any combo shows up fast:
# .github/workflows/ci.yml
matrix:
php: ['8.3', '8.4', '8.5']
laravel: ['12.*', '13.*']
# ...
- run: composer require "laravel/framework:$ matrix.laravel " --no-interaction --no-update
- run: vendor/bin/pest --no-coverage
Pest without a big-bang rewrite
The trick to migrating tests is don’t rewrite them all at once. Pest runs class-based PHPUnit tests unchanged via its interop layer, so the ~hundreds of existing test_* methods keep passing while new tests are written Pest-native.
The bind is one line in tests/Pest.php:
uses(TestCase::class)->in('Unit', 'Visuals', 'Feature');
And new tests read the way Pest tests should — fluent, no class boilerplate:
use function PestLivewirelivewire;
it('builds a configurable column fluently', function ()
$column = Column::make('Name', 'name')->sortable()->searchable();
expect($column->getTitle())->toBe('Name')
->and($column->isSortable())->toBeTrue()
->and($column->isSearchable())->toBeTrue();
);
So the migration is incremental: old suite stays green, new work goes Pest-first.
A workbench you can actually click
Testing a UI package against assertions only gets you so far. M2 adds an Orchestra Testbench workbench — a tiny real Laravel app inside the package you can boot and click through:
composer build # testbench workbench:build
composer serve # testbench serve
It ships demo models (Owner, Species, Breed, Pet), a seeder, and a DemoPetsTable Livewire component, so you can see the table render against real data instead of imagining it from a test name. For a component library, that’s the difference between “tests pass” and “it actually looks right.”
What’s next
The heavy refactor is still ahead (M6): the component composes ~26 load-order-dependent With* traits and inlines theme branches across ~59 Blade files. That sprawl is the real target — but the rule is behaviour-preserving and test-guarded. Today’s job was getting onto Laravel 13 + Livewire 4 with a green Pest suite first, so the refactor has a safety net.
If you’re maintaining a package and upstream says no to the version you need: fork it, but bring the tests. The test harness is what makes a fork maintainable instead of a liability.
