animation="none"Instant state changes. For dense tables and dashboards.
Accessible, animated rating components for React: stars, hearts, smileys, numeric scales, thumbs and review summaries. Fractional precision, keyboard and touch, RTL, forms and SSR included.
npm install react-advanced-ratingRatingTry it. Five stars celebrates.
Playground
Every control maps to a real prop. The snippet updates as you change things, and copy gives you exactly what's rendered.
import { useState } from "react";
import { Rating } from "react-advanced-rating";
import "react-advanced-rating/styles.css";
export function ProductRating() {
const [value, setValue] = useState(3.5);
return (
<Rating
value={value}
onChange={setValue}
precision={0.5}
size={40}
labels={["Terrible", "Bad", "Okay", "Good", "Excellent"]}
showLabel
/>
);
}
Motion
Fills cascade with a stagger, commits pop with a spring, and top scores can celebrate. Everything runs on CSS transitions and the Web Animations API: no animation library, and no React re-renders per frame. Users who prefer reduced motion get instant changes.
animation="none"Instant state changes. For dense tables and dashboards.
animation="subtle"A quick fade-fill and a light pop. Feels professional.
animation="spring"The default. Springy hover, a cascading fill and a ripple on commit.
animation="playful"Bouncy and tilted, with a particle burst on the top score.
Whole stars only, an instant swap, and nothing to confirm that a choice was registered.
The half-star preview follows the pointer, a tooltip names the value, and a springy pop confirms the choice.
Recipes
Each example below is live, and you can open its code.
Sample product
Trail Daypack 22L
$89.00
How was your checkout experience?
Was this article helpful?
How likely are you to recommend us to a friend?
Exactly as described. Fast delivery.
Sam K.Great quality, strap could be softer.
Priya R.Third one I've bought. Love it.
Jonas W.Zip broke after a month.
Lee M.Fine for the price.
Ana G.Fits a 16" laptop with room to spare.
Omar T.Arrived damaged; refund was quick.
Chen L.Comfortable on long walks.
Maya B.Quick start
Import the component and the stylesheet once. Works with Vite, Next.js (app & pages router), Remix and CRA.
import { useState } from "react";
import { Rating } from "react-advanced-rating";
import "react-advanced-rating/styles.css"; // once, anywhere in your app
export function ReviewStars() {
const [value, setValue] = useState(0);
return <Rating value={value} onChange={setValue} precision={0.5} label="Your rating" />;
}value + onChange, or defaultValue."use client".--rar-active-color.rating, editable, starColor…) still work. See the migration guide.Accessibility
Interactive ratings follow the WAI-ARIA slider pattern; read-only ones are announced as a single image with the value in its name.
| Key | Action |
|---|---|
| → / ↑ | Increase by one step (← in RTL) |
| ← / ↓ | Decrease by one step (→ in RTL) |
| Page Up / Page Down | Increase / decrease by 1 |
| Home / End | Minimum / maximum |
| 1–9 | Jump to that value |
| 0, Backspace, Delete | Clear (when allowClear) |
aria-valuetext reads “3.5 out of 5, Good” and is fully customisable for i18n.forced-colors) support.required blocks submit, focuses the control and links the message via aria-describedby.theme="contrast" when state must meet 3:1 non-text contrast on light surfaces.API
Full reference, types and recipes are in the README.
| Prop | Type | Default | Description |
|---|---|---|---|
value / defaultValue | number | 0 | Controlled or initial value. 0 means no rating. |
onChange | (value: number) => void | - | Called on commit; receives 0 when cleared. |
onHoverChange | (value: number | null) => void | - | Live preview value while hovering or scrubbing. |
max | number | 5 | Number of items (1–100). |
precision | number | 1 | Selectable step: 1, 0.5, 0.25, 0.1 or any value in (0, 1]. |
readOnly / disabled | boolean | false | Display-only (role=img) or inert slider. |
allowClear | boolean | true | Clicking the current value, Backspace or 0 clears it. |
icon / emptyIcon | "star" | "heart" | "circle" | "bolt" | "smiley" | "number" | ReactNode | fn | "star" | Built-ins, any SVG/emoji, or a render function. |
highlight | "range" | "single" | "range" | Fill up to the value, or only the selected item (smileys default to single). |
color | string | string[] | (value, max) => string | theme | Active colour; arrays and functions create colour scales. |
theme | "gold" | "rose" | "violet" | "emerald" | "ocean" | "mono" | "contrast" | "gold" | Built-in palettes. |
size / gap | "xs"–"xl" | number | CSS length | "md" | Icon size and spacing. |
animation | "none" | "subtle" | "spring" | "playful" | "spring" | Motion personality (reduced motion respected). |
celebrate | boolean | "max" | number | playful → max | Particle burst on selection. |
labels / getLabelText | string[] / fn | - | Words per value and the screen-reader text (i18n). |
label / helperText / error | ReactNode | - | Visible label, description and validation message. |
showLabel / tooltip | boolean | fn | false | Show the current label next to or above the icons. |
name / required / form | string / boolean | - | Native form integration and validation. |
dir | "ltr" | "rtl" | inherited | Right-to-left support; auto-detected from the DOM. |
Also exported: useRating, ThumbsRating, RatingSummary, computeRatingStats and the icon components (StarIcon, HeartIcon, FaceIcon…).