mlsolutions/nova-dashboard
A Laravel Nova package for building custom dashboards, letting you organize cards, metrics, and other Nova tools into tailored dashboard layouts for your admin panel.
Architecture fit. mlsolutions/nova-dashboard is a Laravel Nova tool, not a standalone service. It occupies the same architectural slot as Nova's built-in dashboard: a service provider registers dashboards, cards and metrics, config is published into config/, and frontend assets land in public/vendor/. For a product already running Laravel + Nova, that is a near-zero-friction fit — no new runtime, no sidecar, no data store beyond the one Nova already uses. The problem it targets is real: Nova's default dashboard is a single Main screen, and every team that has wanted per-role or per-persona dashboards has hand-rolled one. A TPM should read "the missing dashboard for Nova" as layout and curation, not analytics — this is an admin-surface accelerator, not a BI layer.
Integration feasibility. The happy path is short: composer require, publish config and assets, verify the provider auto-registers, confirm the dashboard route renders, then populate with first-party Nova metric cards. The genuine unknowns are not in the code path but in the version matrix. Nova is closed-source and has broken card/metric APIs between majors (v3 → v4 → v5); a package released 2025-06 is pinned to some Nova major and the metadata does not say which. Second unknown: whether frontend assets ship pre-compiled. If they don't, integration inherits an npm/Vite build step against Nova's specific toolchain — a support burden that lands on whoever owns the admin app. Third: whether the package replaces, augments, or shadows the native dashboard. A TPM needs that answered before promising anything downstream, because "we can always fall back to stock Nova" is the cheapest insurance available.
Technical risk. High, and almost entirely adoption-driven rather than code-driven. Two stars, zero dependents, a 0.01 score, and a single-maintainer release cadence mean no third-party production signal and no organic bug-reporting pressure. MIT licensing is the real mitigant — it makes vendoring or forking viable — but the licensing comfort should not be mistaken for operational comfort. The specific risks a TPM should carry on the register: (1) abandonment, with no upstream fix path for a Nova upgrade; (2) authorization surface — any package that renders arbitrary cards and metrics per user or role is a privileged code path, and a scoping gap there is a data-exposure incident inside the admin panel, not a cosmetic bug; (3) migration footprint — purely additive tables are fine, alterations to existing Nova tables are not; (4) any new routes or controllers introduced by the provider, which need the same authz review as first-party code; (5) test coverage, which is unknown and which the adopting team will effectively be replacing with their own feature tests.
Key questions to resolve before adoption.
Verdict. Right category, low integration cost, insufficient evidence for standard-of-record. This is a conditional pilot — a time-boxed spike against one internal dashboard, with a written build-vs-fork decision at the end of it.
Stack fit. Gated entirely on the platform already being Laravel + Nova and the team owning that admin surface. There is no value outside Nova, and adopting it commits the admin app to that ecosystem's upgrade cadence. If the org is standardizing on Filament or a different admin framework, this evaluation ends immediately.
Migration path. Favor composition over dependency. The highest-leverage pattern is to treat the package as a shell and layout engine and populate it exclusively with Nova's own Value, Trend, Partition, and Progress cards. That keeps metric logic on supported, first-party APIs and means an abandoned package strands layout, not data. Concretely: register one dashboard for one persona (e.g. support operations), confirm it renders and authorizes correctly, then decide whether to expand to additional personas or to copy the card list into a project-owned dashboard class under app/Nova/Dashboards. The second path — vendoring — should be the expected end state, not the contingency. Keep all customization in app code; nothing under vendor/ survives a composer update.
Compatibility. Pin the Nova major before installing, and pin the package to an exact version with the lockfile committed. Resolve composer.json constraints against the existing lockfile as the first spike task — a resolver conflict ends the evaluation for the cost of an hour. Re-verify against Nova and PHP minor bumps on an explicit schedule, because with zero upstream dependents the adopting team is the integration test suite.
Sequencing. Four stages, each with a stop/go:
php artisan about), confirm routes register (php artisan route:list | grep -i dashboard), confirm assets resolve in the browser. Stop if any of the first three fail.canSee() scoping enforced, heavy metric queries wrapped in Cache::remember() with a short TTL. Add a feature test asserting 200 for an authorized user and 403 for an unauthorized one — this is the regression net across Nova upgrades.canSee behavior and the multi-tenant scoping. This is the gate that matters; a permissive default here is a production incident waiting for a URL guess.Deliberately deferred: per-user layout persistence. It is the most attractive feature and the most likely to be half-supported; implement it against a project-owned preferences table rather than package internals, and only after the pilot proves the shell is stable.
Maintenance. The realistic annual cost is small but non-zero, and it is engineering cost, not vendor cost. Budget: an owner for the pin, one compatibility re-validation per Nova or PHP minor, and a standing readiness-to-fork task. The MIT license means maintenance risk is capped at "we take the code," which is the right shape for internal tooling — but that cap only holds if the code stays small and the team has actually read it. Anyone approving this should approve it as source we are adopting, not software we are buying.
Support. There is no support. No vendor, no community, no Stack Overflow corpus, no third-party blog posts. The README and the src/ directory are the documentation. That has a direct staffing implication: whoever debugs a blank dashboard at 5pm needs to be able to read the service provider, the dashboard class, and the card registration — not file a ticket. This is fine for a team with Laravel depth and disqualifying for one without.
Scaling. Load characteristics are those of the admin panel, not the product: low request volume, high query cost. Dashboards are typically the most-hit page in a Nova install and the easiest place to accidentally fire five aggregate queries per request. The mitigations are conventional and must be treated as mandatory rather than nice-to-have — cache expensive calculate() calls keyed by range and tenant, cap card counts per dashboard, and review metric queries as part of code review. Vertical scale is not the concern; query cost in production databases is.
Failure modes. Ranked by likelihood and blast radius:
Call to undefined method on a card or metric. Suspect Nova version drift before package bugs. This is the expected failure at every Nova upgrade.main, it shadows the stock dashboard; the symptom is a confusing 404, the fix is a rename.config:clear.Establish a standing debug order so on-call doesn't rediscover it: (1) is the provider loaded, (2) do routes register, (3) do assets resolve, (4) do the card classes exist and return data, (5) authorization.
Ramp-up. Low for the team, negligible for users. Engineers need a day to read the source and understand the registration model, and the patterns involved — service providers, Nova cards, canSee scoping — are ones a Nova-fluent team already has. End users see a new page in an admin they already use; no training, no workflow change beyond pointing at a better starting screen. That low ramp-up is precisely why the opportunity is worth a time-boxed spike and precisely why it is not worth an extended commitment: the ceiling is a modest internal productivity gain, and the package should be sized accordingly.
How can I help you explore Laravel packages today?