PHPackages                             mwebbers/laravel-code-commons - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. mwebbers/laravel-code-commons

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

mwebbers/laravel-code-commons
=============================

Shared Laravel/Livewire conventions: typed mixed-narrowing (Json), reusable stable sortable-table and pagination concerns, a lazy-table skeleton, and a SCOPE&lt;-&gt;test coverage checker.

v1.0.0(1mo ago)0127MITPHP ^8.3

Since Jul 3Compare

[ Source](https://github.com/mwebbers/LaravelCodeCommons)[ Packagist](https://packagist.org/packages/mwebbers/laravel-code-commons)[ RSS](/packages/mwebbers-laravel-code-commons/feed)WikiDiscussions Synced 1w ago

READMEChangelogDependencies (14)Versions (7)Used By (0)

LaravelCodeCommons
==================

[](#laravelcodecommons)

Shared Laravel/Livewire conventions, packaged once instead of hand-copied per project. These pieces used to live as near-identical copies across consuming apps and drifted; this package is the single canonical home.

Requires **PHP 8.3+** and `illuminate/support ^13.8` (Laravel 13). MIT-licensed.

Install
-------

[](#install)

```
composer require mwebbers/laravel-code-commons
```

Until it is on Packagist, add the repository to the consuming app's `composer.json`:

```
"repositories": [
    { "type": "vcs", "url": "https://github.com/mwebbers/LaravelCodeCommons" }
]
```

What's in it
------------

[](#whats-in-it)

### `Support\Json` — typed `mixed` narrowing

[](#supportjson--typed-mixed-narrowing)

The single sanctioned place a JSON/`config()` `mixed` becomes a real type, which is what lets a consuming app keep PHPStan at **level 10** without scattered casts. Every accessor degrades to a default instead of crashing on a wrong-typed or missing value.

```
use Mwebbers\LaravelCodeCommons\Support\Json;

Json::str($node['title'] ?? null, '(untitled)');   // string, scalars stringified
Json::int($config['limit'] ?? null, 50);           // int, numeric strings coerced
Json::rows($response->json());                      // list — non-array rows dropped
```

### `Livewire\Concerns\WithCollectionSorting` — a stable sortable-table concern

[](#livewireconcernswithcollectionsorting--a-stable-sortable-table-concern)

Click-to-sort for a Livewire table over an in-memory collection. Owns only the sort *state* and the toggle; the host supplies a `column => extractor` map. The sort is **stable in both directions** — equal-key rows keep their natural order whether ascending or descending (it uses `sortByDesc`, never a `reverse()` of the ascending sort, which would flip ties). Uses only Illuminate collections, so the logic is testable without a Livewire runtime.

```
use Mwebbers\LaravelCodeCommons\Livewire\Concerns\WithCollectionSorting;

class Tickets extends Component
{
    use WithCollectionSorting;

    public function render()
    {
        $rows = $this->sortedBy($this->tickets(), [
            'title'    => fn ($t) => $t->title,
            'deadline' => fn ($t) => $t->deadline?->getTimestamp() ?? PHP_INT_MAX,
        ]);
        // ...
    }
}
```

`Livewire\TableRow` is a tiny typed row DTO shipped as the reference shape to sort over (a generic `callable(TValue)` does not narrow an array-shape closure param under level 10, so a typed object keeps the example clean).

### `Livewire\Concerns\WithCollectionPagination` — paginate an in-memory collection

[](#livewireconcernswithcollectionpagination--paginate-an-in-memory-collection)

Composes the sort concern with Livewire's pagination: it paginates an already-derived collection at `perPage()` rows, renders one page at a time, and **resets to page 1 when the sort changes**. An **out-of-range `?page=` clamps to the last real page** — the URL is user-controlled input, and the data exists (just not 99 pages of it), so an empty table would be misleading. For a query builder use Livewire's native `->paginate()`; this is for a set you already hold in memory.

### `Livewire\Concerns\LazyTableSkeleton` — a `#[Lazy]` table's placeholder

[](#livewireconcernslazytableskeleton--a-lazy-tables-placeholder)

Pairs with `#[Lazy]` to render a skeleton while the table body hydrates in a second request. It uses the page's **real column headers** so the skeleton auto-sizes like the live table (no layout shift). The placeholder **view is app-provided** — ship a `livewire.placeholders.table` Blade view (it carries your design system, e.g. Flux), or override `skeletonView()` to point at your own; a host overrides `skeletonColumns()` / `skeletonRows()` to match its table. A `skeletonColumns()` entry is either a bare label or a `'label' => alignment` pair (`start`/`center`/`end`), so a column the live table end-aligns starts where it will end up — the view normalizes both forms. One caveat: a purely numeric label (`'2024'`) cannot carry an alignment pair, because PHP coerces such array keys to int.

### `Testing\ScopeCoverage` — the SCOPE↔test traceability checker

[](#testingscopecoverage--the-scopetest-traceability-checker)

A coverage gate, extracted so every consuming app runs the **same** checker instead of a hand-copied `ScopeCoverageTest`. It reads the feature IDs from a `SCOPE.md` `## Features` section and the `#[Group('F-00X')]` references across a tests directory, and reports either side's gaps.

An app's `ScopeCoverageTest` becomes a thin wrapper:

```
use Mwebbers\LaravelCodeCommons\Testing\ScopeCoverage;
use PHPUnit\Framework\TestCase;

final class ScopeCoverageTest extends TestCase
{
    public function test_scope_and_tests_stay_in_sync(): void
    {
        $coverage = new ScopeCoverage(dirname(__DIR__, 2).'/SCOPE.md', dirname(__DIR__, 2).'/tests');
        $result = $coverage->mismatch(__FILE__);

        $this->assertSame([], $result['missing'], 'SCOPE features with no test: '.implode(', ', $result['missing']));
        $this->assertSame([], $result['stale'], 'Test groups for unknown features: '.implode(', ', $result['stale']));
    }
}
```

Roadmap
-------

[](#roadmap)

Planned for later minors: a `DuskTestCase` base for browser smoke tests, and publishing to Packagist (so consumers can drop the VCS `repositories` entry). See `CHANGELOG.md`.

Development
-----------

[](#development)

```
composer install
composer lint      # pint --test
composer analyse   # phpstan level 10
composer test      # phpunit
```

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance93

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

5

Last Release

35d ago

Major Versions

v0.3.1 → v1.0.02026-07-19

### Community

Maintainers

![](https://www.gravatar.com/avatar/3e37a1078a75a9ff3bb65e76d38bb767cfb36a85c3c79ad4e32600f3a46730b5?d=identicon)[Michael Webbers](/maintainers/Michael%20Webbers)

---

Tags

laravellivewirestructurecommonsscope-driven

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/mwebbers-laravel-code-commons/health.svg)

```
[![Health](https://phpackages.com/badges/mwebbers-laravel-code-commons/health.svg)](https://phpackages.com/packages/mwebbers-laravel-code-commons)
```

###  Alternatives

[livewire/flux

The official UI component library for Livewire.

9628.9M160](/packages/livewire-flux)[tallstackui/tallstackui

TallStackUI is a powerful suite of Blade components that elevate your workflow of Livewire applications.

731189.9k16](/packages/tallstackui-tallstackui)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.8k](/packages/tomshaw-electricgrid)[venturedrake/laravel-crm

A free open source CRM built as a package for laravel projects

45212.2k1](/packages/venturedrake-laravel-crm)[getartisanflow/wireflow

Livewire components for AlpineFlow — build interactive flow diagrams in Laravel.

9624.2k](/packages/getartisanflow-wireflow)[forjedio/inertia-table

Backend-driven dynamic tables for Laravel + Inertia.js

272.0k](/packages/forjedio-inertia-table)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
