wamesk/rating-field
A lightweight Laravel package that adds a ready-to-use star rating field to your forms, letting users pick a score with a simple, configurable star widget. Quick to install and easy to drop into existing forms.
What this actually is. Despite a description that advertises a general "Laravel package" for "your forms and admin resources," wamesk/rating-field is a Laravel Nova field only. It requires a licensed Nova install. In a non-Nova application, it does nothing. That gap between the README and the runtime is the first thing to correct in any planning document, because it changes the scope of the request: this is a staff-facing admin-panel UX decision, not a product capability.
Architecture fit. Where Nova is already in use, the fit is clean and shallow. The package is a Nova Field subclass plus a Vue single-file component — no service layer, no domain model, no migrations of its own. It stores a plain integer or decimal in a column you define, which means it composes with standard Laravel validation, casts, factories, and query sorting with zero ceremony. That narrowness is the virtue: it is a presentation-layer input, and it stays in the presentation layer.
Integration feasibility. Low effort, roughly half a day end to end. The work is not installing the package — it is deciding the storage contract (whole stars vs. half-stars vs. required), writing the migration and cast, wrapping the vendor class in a thin App\Nova\Fields\Rating subclass, and smoke-testing the widget on one resource. No data migration, no backfill, no API surface change.
Technical risk. Concentrated and asymmetric: the failure mode is silent and the maintenance risk is total.
php artisan nova:field, so the correct move on Nova 5 is to build, not port.decimal(2,1) paired with an integer validation rule rejects every half-star the UI produces, with an error message staff will not read. Column, cast, validation rule, and client step must change in a single commit with a round-trip test.<i> with no focusable control or ARIA value, it needs wrapping or replacing.Key questions for the team.
Stack fit. Laravel + Nova, both already present. The package touches nothing else. It writes a scalar column, so Eloquent casts, factories, FormRequests, and index sorting all continue to work unchanged. Factories should never need to know about the field; if they do, presentation has leaked into the domain.
Migration path. The cheapest honest path is not "adopt a dependency" — it is vendor the source. One composer require at an exact pin (wamesk/rating-field:0.1.0, no caret), then copy src/ into app/Nova/Fields/Vendor/Rating/, keep the copyright header and a NOTICE line, drop the composer dependency, and assign a named owner. The license (almost certainly MIT — confirm) permits this. This converts an unmaintained third-party dependency into internal code with a known blast radius, at a cost of about an hour.
Compatibility. Gate on Nova major before anything else: composer show laravel/nova. Then read the <script> block of resources/js/components/Field.vue — Options API means Nova 4/Vue 2, defineComponent/<script setup> means Nova 5/Vue 3. Also check whether the package ships a prebuilt dist/ bundle (publish assets only, do not run a local build against it) or raw sources (must be built through the Nova asset pipeline). Confirm fluent method names from src/Rating.php rather than guessing from the README.
Sequencing.
unsignedTinyInteger nullable + integer cast; half-stars → decimal(2,1) nullable + decimal:1 cast + numeric validation; required → no null.Rating::score() factory method so every call site is one line.->rules() echo it. Nova field rules are skipped by imports, artisan commands, and API writes.?orderBy= on the column. Fall back to ->exceptOnIndex() + a plain Number field if index rendering cannot show stars correctly.Rollback story. A Number field with min/max and a suffix, documented in the runbook. It costs nothing and removes the "we're stuck" failure mode from the deploy-day conversation.
Maintenance. Effectively zero upstream: assume no future releases. Internal maintenance is the wrapper class plus a ~45-line Vue component — small enough that a single engineer can hold it. Publishing views or the Vue SFC should be treated as forking-lite and recorded in the runbook, because upstream changes will never merge cleanly (and will never arrive). Prefer configuring via fluent/meta options over publishing config, so per-resource tweaks don't require a config:cache cycle.
Support. No vendor support channel exists. Support means internal ownership: one named engineer, one runbook entry. That entry is one line — "Rating field, vendored from wamesk/rating-field, revalidate form/detail/index under new Nova major; fallback is Number with min/max" — and it is the entire mitigation for the quiet-failure risk.
Scaling. The data layer scales trivially: a single indexed tinyint or decimal column, sortable and aggregatable in SQL. The package itself does not scale into anything — the moment the requirement becomes averages, per-user vote history, "sort the list by rating," or customer-facing stars, the field is finished and the real work (a domain model and aggregation query or cached column) begins. Price that separately; no field package does it for you.
Failure modes.
| Failure | Symptom | Detection | Mitigation |
|---|---|---|---|
| Stale/missing asset bundle | Plain number input or blank; form still submits | Browser smoke test only | Release-checklist check on every Nova asset deploy |
| Nova major upgrade | Widget does not mount | Manual revalidation after upgrade | Runbook entry + Number fallback |
| Half-star type drift | All half-stars rejected with an unread error | Automated round-trip test on 3.5 |
Change column/cast/rules/step in one commit |
0 vs null confusion |
Unrated rows render empty stars, indistinguishable from zero | Visual review of index | nullable() everywhere; displayUsing() to render — |
| Accessibility gap | Keyboard/screen-reader users cannot operate or read the field | Manual tab/arrow-key pass | Wrap or replace the component if it lacks ARIA value |
Ramp-up. Roughly half a day for an engineer familiar with Nova: ~45 minutes reading the two source files, the rest on migration, wrapper, and browser verification. A TPM needs almost no ramp-up beyond the two facts that govern every downstream decision — Nova-only, and pinned to the Nova 4/Vue 2 generation until proven otherwise.
Bottom line for the roadmap. This is a UX nicety for internal ops tooling — QA scorecards, vendor grading, triage prioritisation, content-quality scoring — not a differentiator and not a capability purchase. It should not consume a sprint. The defensible decision is to vendor the source and own it, or, on Nova 5, to scaffold an equivalent in-house field for roughly the same cost. Both are legitimate; adopting it as a maintained third-party dependency is not.
How can I help you explore Laravel packages today?