elevate-digital/nova-charcounted-fields
A Laravel Nova package that adds character-counted text fields with live counts and length-limit support. Ideal for titles, excerpts, meta descriptions, and other constrained content, helping editors stay within required limits while composing in Nova. Easy to configure and integrate into existing r...
What it is. A Laravel Nova field package that subclasses Nova's built-in Text and Textarea fields and ships a Vue form component adding a live character counter (and, by convention, client-side maxlength enforcement). It is a presentation-layer convenience, not infrastructure: no migrations, no service provider logic beyond asset registration, no server-side validation, no persistence layer.
Architecture fit. Fit is narrow and well-defined. It only has value inside a Laravel Nova admin panel — Nova is a commercially licensed first-party package, so this dependency is confined to internal tooling and can never be part of a shipped product surface. If the estate has no Nova, or is standardising away from Nova toward Filament/Inertia-built admin, the package has zero applicability and the evaluation ends here. Where Nova is in use, the fit is clean: it is a drop-in field swap (Text::make() → CharCountedText::make()) with no schema or model impact.
Integration feasibility. Mechanically trivial — composer require elevate-digital/nova-charcounted-fields, then substitute the field classes in resources. The real friction is version compatibility, not effort. The dominant risk is Nova major-version drift: Nova 4 moved to Vue 3 and a new asset/build toolchain (nova.mix.js), and Nova 5 continues that line. A field package compiled against Nova 3's Vue 2 components will not render its counter under Nova 4/5 without a rebuild. Composer constraints on laravel/nova will usually surface this as an install failure rather than a runtime one — which is the good outcome.
Technical risk.
max: validation rule, oversized payloads reach the model and produce truncation or a strict-mode SQL error..length counts UTF-16 code units; emoji and some CJK glyphs count as 2, while PHP mb_strlen counts 1. A counter reading "98/100" can fail a max:100 rule, or vice versa.dist/js/field.js is a committed artifact; if you cannot rebuild it from source against your Nova version, you cannot patch it.Key questions.
composer.json permit, and does the committed dist bundle match the current Nova toolchain?Stack fit. Requires Laravel + Nova with matching major versions; PHP constraint must align with the app's runtime. No database, queue, cache, or API surface — the compatibility matrix is essentially one axis (Nova version) plus one axis (PHP version).
Migration path. Low ceremony, fully reversible:
max: rule (or Str::length custom rule) sized to the column, and decide explicitly how multibyte input is counted.Compatibility. Verify the Nova major version first, before any install attempt — this is the single gate. Secondary checks: PHP version, and whether the app's build pipeline needs to recompile the field assets (it does not, if you use the committed dist).
Sequencing. Do not sequence this ahead of anything. It is a cosmetic refinement to be picked up opportunistically alongside other Nova admin work. If a fork or rebuild is required for Nova 4/5, the decision to adopt flips: at that point you are maintaining a private fork of a package nobody else uses, and building the component in-house is the cheaper, better-owned option. My recommendation is rebuild in-house or vendor a copy unless the spike shows a clean, current, licence-permissive package — the dependency buys you roughly a day of work in exchange for an unowned moving part.
Fallback. Native Nova Text::make()->maxlength() plus a help() hint covers enforcement; only the live counter is lost. Confirm with product whether the counter is a genuine UX requirement or a nice-to-have before investing further.
Maintenance. Effectively zero ongoing cost if Nova versions stay pinned; unbounded cost at the next Nova major upgrade, because the fix is a JS rebuild that upstream may never ship. Budget a standing "verify after Nova upgrade" check in the admin regression suite. Because the package is abandoned-adjacent, assume the team owns the code in practice even if not in name — capture the fork internally if adopted.
Support. No vendor SLA, no issue throughput, no release cadence to track. Internal support burden is limited to the field classes themselves; any bug becomes your bug. Document the source of truth (fork URL, build command) in the repo README so it survives staff turnover.
Scaling. Not a consideration in the conventional sense — the counter is client-side and per-request; no runtime footprint, no load characteristics, no infrastructure change. The only "scaling" concern is organisational: every resource that adopts the field adds another place to update if the component is later replaced.
Failure modes.
Ramp-up. Near-zero for a Laravel developer — the API mirrors Nova's own fields, so the learning curve is "swap the class name." The genuine ramp-up cost is institutional: someone must be able to rebuild the JS bundle, which means keeping Node, the Nova build tooling, and the source in a working state. If the team cannot rebuild it, the package is unmaintainable by definition and should not be adopted.
Bottom line. Low opportunity is the correct read. This is a convenience wrapper whose entire value is a character counter, whose differentiation is a day of engineering, and whose ownership and compatibility risk exceed that saving on any Nova 4/5 estate. Verify licence and Nova compatibility if a spike is cheap; otherwise build or vendor the component and keep the dependency count flat.
How can I help you explore Laravel packages today?