savannabits/admin-listing
savannabits/admin-listing is a Laravel package for quickly building admin listing pages. Declare columns, search, filters, sorting, and row actions in one configurable class, then get paginated, Blade-rendered tables out of the box. Ideal for CRUD backends and internal tools.
Architecture fit. This package occupies a narrow, legitimate slot: a server-rendered Blade admin-listing layer that wraps Eloquent query building — configurable columns, server-side search/sort/filter, pagination, and row actions. That is a sound architectural fit only if our admin surface is classic Laravel + Blade. If our baseline is Filament, Livewire, Inertia/Vue, or an API-first admin SPA, the package's entire value proposition evaporates and we would spend the integration budget fighting its assumptions rather than benefiting from them. The second fit axis is coupling: the value depends on per-model listing classes being the team's standard pattern, not a one-off.
Integration feasibility — the honest read. Install is trivial (composer require), but feasibility is gated by a version question, not a code question. The release record references a v7.0.1 line while the last publish date is 2020-05-15; the version number almost certainly tracks Laravel 7, not the package's own major. That discrepancy must be reconciled before it informs any decision — it is a diligence flag, not a footnote. If our fleet baseline is Laravel 10/11, feasibility collapses to zero and the evaluation ends there.
Technical risk — the dominant factor. Upstream is effectively dormant: 0 stars, 0 dependents, no documentation, no upgrade guide, no visible maintainer capacity. The composite score of 0.3 is not a quality verdict on the code so much as a measurement of ecosystem signal, and there is none. Concretely, adopting this means buying a starting point, not a dependency — the "buy" is really "fork and own." Secondary risks: a 2020-era package likely assumes Bootstrap 4 pagination markup and possibly jQuery-dependent action-confirmation JS; the changelog entry "Dependencies Updated" can mask transitive minor-version drift that fails quietly at boot; and there is no security-patch turnaround path, which is disqualifying for any surface touching regulated data.
Key questions for the spike.
composer.json actually intersect it?app/" or "rewrite on a maintained framework"? Decide before, not during, an urgent admin feature.Stack fit is a gate, not a preference. Confirm the Blade + Bootstrap-era assumptions against our admin shell first. If our shell is Tailwind/Livewire, budget for overriding published pagination and action views — and treat that override cost as part of the comparison against maintained frameworks, not as an afterthought.
Migration path — two viable shapes, one recommended.
composer.lock delta as the rollback artifact, publish config and views immediately so future upgrades surface as reviewable diffs rather than a black box, and record the exit trigger in writing.Compatibility work, in order. Read the package's composer.json constraints before writing a listing. Read the service provider (bindings, auto-discovery, publish tags), then the base listing class (the entire API surface — constructor, query hook, columns, actions), then the Blade views (the rendered output our layout must accommodate). Source is the contract; there are no external docs.
Sequencing.
User — columns for name/email/created_at, name+email searchable, created_at sortable, wired into an existing admin middleware group. This proves routing, layout integration, and pagination rendering in about an hour, before any delete flow or custom renderer exists.Authorization boundary — pin this in the convention. Row actions are a UI affordance, not a security boundary. The listing renders edit/delete conditionally and the destroy action re-checks authorization. Deletes are POST forms with @csrf and @method('DELETE'), never GET links.
Maintenance — we would be the maintainers. With no upstream activity since 2020 and no community to inherit fixes from, every bug becomes internal work and every Laravel/PHP upgrade becomes a compatibility project. The realistic ownership cost is not the install; it is the fork, the periodic rebase, and the eventual migration off. For a long-lived product this dominates the calculus. For a throwaway prototype or single-tenant internal tool with a bounded lifespan, it may be acceptable — say so explicitly if that is the bet.
Support and escalation. There is no support path: no maintainer SLA, no upgrade guide, no issue-triage expectation. Escalation for any defect is "an engineer on our team fixes it." That is survivable for internal, authenticated, low-blast-radius surfaces and unacceptable anywhere with a customer-facing SLA or regulated data exposure.
Scaling — three predictable cliffs.
$row->team->name without eager loading is one query per row per page. Put with([...]) in the query hook so every consumer benefits, and check query count on a 50-row page before shipping.orderBy is a silent performance cliff. Restrict LIKE to term% where possible and confirm exposed columns are indexed.per_page. Clamp to an allowed set (10/25/50/100) in the listing class; an open per_page is a cheap way to trigger a full-table scan.Failure modes to instrument for.
->toSql() plus bindings) and logging the request parameters the listing reads — not by staring at the response.config:cache and our settings live only in package defaults, edits silently no-op. Publish config ahead of any cache step and diff against package defaults on every bump.Ramp-up. Low in absolute terms, because the API surface is three files and the source is readable. Expect roughly a day for an engineer to read the provider, base class, and views, and an hour to a working read-only listing. The real ramp cost is organizational: writing the convention and getting two or three teams to adopt it is where the leverage is, and it is the same amount of work whether we build on this package or a maintained one. Test at the route level — a feature test asserting a known row appears and an unauthorized user gets 403 catches more real regressions than unit-testing the listing class.
Metrics for the next two deliverables. Per-screen effort against the current baseline, number of listing classes reusing the shared base, and zero regressions in admin authorization tests. Success is the next three admin screens costing days instead of weeks — a target a maintained framework reaches with less residual risk than a dormant package ever will.
How can I help you explore Laravel packages today?