david-griffiths/nova-dark-theme
A dark theme for Laravel Nova that gives the admin panel a sleek, low-light look and reduces glare during long sessions. Easy to install and configure, it restyles Nova's UI for comfortable everyday use.
Architecture fit. This is a presentation-layer package and nothing more: a stylesheet override set, a Vue toggle component, and Artisan commands that scaffold that toggle into Laravel Nova templates. It touches no routing, auth, queues, persistence models, or business logic, so architectural coupling is low and the change is reviewable in an afternoon by a single engineer. The one genuine design decision it forces is where the theme preference lives — localStorage, session cookie, or a user column. That choice determines whether adoption is a stateless, trivially reversible CSS change or a schema migration requiring sequencing against the user table. From a TPM standpoint that is a scoping question to close before the spike, not during it.
Integration feasibility. High for a stock Nova admin panel on the era the package was built for; moderate-to-low for a customized one. Installation is Composer plus service-provider registration, and v1.0 adds Artisan commands that inject a toggle into Nova templates. That demos fast, but it means the package mutates files inside your application rather than only registering itself. The feasibility question for a TPM is therefore not "can we install this" — it is "can we audit, diff, and reverse it." The captured scaffold diff is the deliverable that matters; without it, you have an un-auditable, un-rollbackable change to your admin surface.
Technical risk. The dominant risk is dormancy and version drift, not code quality. Last tagged release is 2019-02-16, 71 stars, zero dependents. The v1.0 notes describe a Vue component and Nova template commands from the Nova 1.x/2.x era; Nova has shipped multiple majors since, and modern Nova uses a different frontend stack and markup conventions. A 2019-era Vue component and selector set is unlikely to work against current Nova without rework — and Nova is closed-source and commercially licensed, so you cannot patch the vendor layer around incompatibilities. You are entirely dependent on a maintainer with no recent release activity. Secondary risks: silent template conflicts from the scaffolding commands, no documented uninstall path, hand-rolled switch accessibility gaps (keyboard focus, role="switch"/aria-pressed semantics, visible label, prefers-color-scheme fallback), and flash-of-wrong-theme if persistence is split between client and server. Intrinsic blast radius is small: a theme toggle is cosmetic, not security-, data-, or availability-critical. MIT clears licensing, and there is no meaningful supply-chain surface beyond Composer.
Key questions.
composer.json? Test against our Nova version, not the README's claim.resources/ templates, or config — and is there a dry-run or a documented uninstall?v1.0 a SemVer stability commitment or simply the first tag? With one release in 2019, assume the latter.prefers-color-scheme.TPM framing. Treat this as an accelerator and a reference implementation, not a strategic dependency. Its value to a TPM is that it converts a vague request — "the admin panel is harsh to look at after eight hours" — into a scoped, estimable, demoable ticket with a known cost ceiling. It gives you a concrete build-vs-buy comparison point and a defensible answer to accessibility and ergonomics requests. It does not merit a platform commitment or a place in the dependency policy.
Stack fit. Presumes Laravel + Blade + Vue on Laravel Nova, at a major roughly contemporaneous with the 2019 tag. Poor fit for Livewire-only, Inertia/React, API-only, or strict-CSP/no-JS admin surfaces. If you are not on Nova, the package's only differentiator — the Artisan commands that wire a toggle into Nova templates — evaporates, and a CSS-variable plus localStorage approach is cheaper, fully owned, and equally good.
Migration path. Run this as a time-boxed spike, not a rollout.
composer.json — no caret range.Compatibility. Pin two axes: PHP/Laravel per composer.json, and Nova major version. Because Nova is closed-source and paid, compatibility is a one-way dependency on the maintainer tracking vendor releases. Check commit history for whether past Nova majors were supported promptly; with no releases since 2019, assume no. Verify the Vue major against your Nova build before anyone writes integration code.
Sequencing. Low urgency, and deliberately ordered:
Maintenance. Upstream is effectively dormant: one release in 2019, zero dependents, 71 stars. Plan on owning the code. Budget a review at each Nova major upgrade plus a periodic dependency audit; if you adopt, assume you fork within a year. Code volume is small enough that forking is a contained cost rather than a crisis. Record the decision in an ADR with the pinned version and an explicit fork trigger — for example, "fork if the toggle breaks on the next Nova major."
Support. No vendor SLA. Support is the issue tracker plus your own reading of a small codebase, which is auditable in an afternoon. Internal support load is low because failures are visible and cosmetic rather than incident-generating. Document the Artisan commands, the captured diff, and the rollback steps in the team runbook; that documentation, not the package, is the durable artifact.
Scaling. Non-issue. The package is CSS and a client-side toggle; it adds no query load, no background processing, and no per-request server cost beyond reading a preference if you persist it server-side. It does not compound with user count or data volume. The scaling risk is organizational, not technical: it becomes one more unowned artifact that silently rots until a Nova upgrade surfaces it.
Failure modes. Bounded and loud rather than silent-but-dangerous:
None of these are incident-severity for an internal admin panel; all are cheap to contain if the spike does its job.
Ramp-up. Near-zero for an engineer already fluent in Nova and Vue — a half-day to install, diff, and demo. The real ramp-up cost is the decision work a TPM owns: confirm the Nova version constraint, settle the persistence question, define the flag, and set the fork trigger. Call it one ticket, one engineer, one day, with a decision at the end and a documented off-ramp. If the spike shows the package fighting your Nova version or the scaffold diff sprawling into published views, stop and spend the half-day on a small internal CSS-variable override instead — the surface area is small enough that in-house ownership is cheaper than carrying an abandoned dependency, and it eliminates the annual Nova-upgrade breakage risk entirely.
How can I help you explore Laravel packages today?