Product Decisions This Supports
- Feature scoping for length-constrained inputs. Any roadmap item involving user-authored short-form content — SEO meta descriptions, page titles, product taglines, bios, SMS/push notification copy, alt text, ad headlines — needs visible feedback while typing. This package is the cheapest way to ship that feedback in Filament admin panels, so scoping conversations shift from "do we build a counter?" to "which fields get one?"
- Build vs. buy, decided in favor of buy. The realistic alternative is 2–4 engineering days wiring custom Blade views and Alpine watchers onto Filament's TextInput/Textarea/RichEditor, then owning emoji/code-point counting, paste and autofill handling, Livewire reactivity, and screen-reader announcements forever. At a 34-star, MIT-licensed footprint, the package is closer to vendoring than adopting a platform: low cost, low lock-in, forkable if the maintainer stops.
- A hard-vs-soft limit policy per field. The package now deliberately separates the two:
characterLimit() is a soft guide (counter only), maxLength() is hard enforcement (blocks paste/typing). That is a genuine product distinction — e.g. soft-limit a meta description so marketing can see guidance but not fight the form; hard-limit an SMS body because the downstream system truncates. This lets you encode product policy in the form layer instead of arguing about it per release.
- Accessibility commitments without a separate workstream. The 5.2.0 work (over-limit state communicated in words, not color alone; message announced to screen readers;
aria-describedby linking input to counter) means form accessibility can be claimed as a side effect of a small dependency rather than funded as its own epic. If you have an accessibility audit on the roadmap, this removes a class of findings from scope.
- Localization roadmap. Counter text is a publishable translation file with community-supplied locales (Dutch, German, French, Arabic, Central Kurdish). If you ship admin UI to non-English markets, this is one fewer string to hand-roll — and it's a place to contribute back rather than maintain privately.
- Platform upgrade sequencing (Filament 4 → 5, Livewire 3 → 4, Laravel 12 → 13). The package declares support across those combinations, so it can be treated as not a blocker in upgrade planning — provided you verify it, since the changelog shows the RichEditor integration breaking in non-obvious ways across releases. This is an input to your upgrade risk register, not just a dependency list entry.
- QA and support-ticket triage. Counter behavior regressions cluster around paste, dictation, autofill, programmatic
$set(), and form resets — not typing. Knowing that lets you target a small, specific test set instead of re-testing the whole form.
When to Consider This Package
Adopt when most of these are true:
- You are on Filament 4 or 5 (v5.x of the package), PHP 8.2+, and a currently supported Laravel (the maintainer no longer tests Laravel 11 due to Composer security advisories).
- Your need is specifically counters on TextInput, Textarea, RichEditor — the three components covered. Anything else is out of scope.
- You want per-field control: conditional display via closure on field state, counter inside vs. outside the control, soft vs. hard limits.
- You are comfortable pinning an exact version and writing a handful of regression tests (paste overflow, emoji counted as one, RichEditor updates, reset behavior).
- Your team can absorb a single-maintainer dependency — or vendoring it is acceptable as a hedge.
Look elsewhere, or re-scope, when:
- You are still on Filament 3.2. Version 1.x exists but predates RichEditor support, the accessibility work, and the reliability fixes — treat it as frozen, not supported.
- You need counters on other field types (TagsInput, Select, custom Livewire components) or non-Filament forms. This won't help; you need a general solution.
- Your primary requirement is server-side hard validation. This is a client-side/UI concern; the source of truth stays Laravel's
max: rule plus Filament's maxLength(). Do not let a visible counter substitute for validation.
- You need vendor assurance: security review, SLA, CVE response commitments, or broad ecosystem validation. At 34 stars and effectively no dependents, the package has minimal third-party vetting — the code is small and readable, but that is your due diligence, not someone else's.
- You need behavioral analytics (typing patterns, truncation rates) rather than visual feedback.
- You need counters inside Repeater/Builder nested fields or other composed structures — not documented as supported, so budget for a spike before committing.
How to Pitch It (Stakeholders)
To executives (30 seconds): A free, MIT-licensed add-on that shows users how many characters they have left in admin form fields — the kind of feedback that stops people from writing a 300-character meta description that gets silently truncated. It is a small dependency, not a purchase, and it also covers accessibility and non-English labels that we would otherwise have to fund as separate work. Cost is roughly a day of integration; the measurable win is fewer corrected resubmissions and fewer "why did my text get cut off?" tickets on content-heavy forms.
To engineering (the real summary): composer require schmeits/filament-character-counter:^5.0, publish the translations tag, swap the imports for TextInput/Textarea/RichEditor, and use characterLimit() for soft guidance or maxLength() for hard enforcement. Since 5.2.0 it depends on filament/forms and filament/support rather than the whole panel package, ships plain CSS with dark-mode variables, has no build step, and requires no view overrides — which matters, because earlier versions copied Filament's RichEditor view and silently disabled attachments, mentions, and floating toolbars. Pin the exact version, add tests for paste/emoji/reset, and re-run those tests on every Filament or Livewire upgrade; the maintainer's own changelog shows limit enforcement semantics flipping once already (characterLimit() hard → soft in 5.0.1), so treat the API contract as something to verify, not assume.