rater-js is a lightweight, dependency-free star rating widget for the browser.
It supports mouse and touch input, fractional ratings, custom star images, and
right-to-left layouts.
- Any number of stars
- Fractional rating steps
- Mouse and touch support
- Right-to-left support
- Read-only ratings
- Custom star size, spacing, images, and text
- Native ES modules for modern bundlers
- Standalone browser build for use without a bundler
- TypeScript declarations included
npm install rater-jsAdd an element that will contain the rating widget:
<div id="rater"></div>Create a rater for that element:
import raterJs from "rater-js";
const rater = raterJs({
element: document.querySelector("#rater"),
rateCallback(rating, done) {
this.setRating(rating);
done();
}
});rateCallback receives the selected rating and a done callback. Always call
done() after synchronous or asynchronous rating work has finished so the
widget can leave its busy state. Inside rateCallback, this refers to the
rater instance.
rater-js is a native ES module. Vite, webpack, Parcel, Rollup, and esbuild can
consume it directly:
import raterJs from "rater-js";
const rater = raterJs({
element: document.querySelector("#rater")
});Load the standalone browser build before the closing body tag:
<script src="node_modules/rater-js/dist/rater-js.iife.min.js"></script>
<script>
const rater = window.raterJs({
element: document.querySelector("#rater")
});
</script>The same file is available from npm CDNs such as jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/rater-js@2/dist/rater-js.iife.min.js"></script>Set the initial value with the rating option:
const rater = raterJs({
element: document.querySelector("#rater"),
rating: 3.5
});You can also provide the initial value through a data-rating attribute:
<div id="rater" data-rating="3.5"></div>const rater = raterJs({
element: document.querySelector("#rater")
});Each call to raterJs creates one independent rater for one element. Create an
instance for every matching element when a page contains multiple ratings:
<div class="rater" data-rating="2"></div>
<div class="rater" data-rating="4"></div>const raters = [...document.querySelectorAll(".rater")].map((element) =>
raterJs({
element,
rateCallback(rating, done) {
this.setRating(rating);
done();
}
})
);The returned array contains the individual instances, so each rater can be updated, disabled, cleared, or disposed independently.
Use step to control the selectable precision. It must be greater than 0 and
no greater than 1:
const rater = raterJs({
element: document.querySelector("#rater"),
rating: 3.5,
step: 0.5
});Stars have a 2-pixel gap by default. Set starSpacing to a non-negative number,
or use 0 for the original layout without gaps:
const rater = raterJs({
element: document.querySelector("#rater"),
starSize: 32,
starSpacing: 6
});const rater = raterJs({
element: document.querySelector("#rater"),
rating: 4.4,
readOnly: true
});Set reverse to true to reverse the rating direction:
<div dir="rtl">
<div id="rater"></div>
</div>const rater = raterJs({
element: document.querySelector("#rater"),
reverse: true
});Use onHover and onLeave to display the value currently under the pointer:
<span id="rater"></span>
<span id="live-rating"></span>const rater = raterJs({
element: document.querySelector("#rater"),
onHover: (currentRating, selectedRating) => {
document.querySelector("#live-rating").textContent = currentRating;
},
onLeave: (currentRating, selectedRating) => {
document.querySelector("#live-rating").textContent = selectedRating || "";
}
});| Option | Type | Default | Description |
|---|---|---|---|
element |
HTMLElement |
Required | Element that will contain the rater. |
rateCallback |
function(rating, done) |
— | Called when a rating is selected. Call done() when processing has finished. The rater instance is available as this. |
max |
number |
5 |
Number of stars to display. |
rating |
number |
No rating | Initial rating. A data-rating value on element is used when this option is not supplied. |
step |
number |
1 |
Rating precision. Must be greater than 0 and no greater than 1. |
starSize |
number |
16 |
Width and height of each star in pixels. |
starSpacing |
number |
2 |
Non-negative gap between stars in pixels. Use 0 for no gap. |
showToolTip |
boolean |
true |
Shows rating text in the element's title attribute while hovering. |
ratingText |
string |
"{rating}/{maxRating}" |
Hover text. Supports {rating} and {maxRating} placeholders. |
disableText |
string |
"{rating}/{maxRating}" |
Tooltip used while the rater is disabled. Supports {rating} and {maxRating} placeholders. |
isBusyText |
string |
— | Tooltip displayed while rateCallback is waiting for done(). |
readOnly |
boolean |
false |
Creates the rater in a disabled state. |
reverse |
boolean |
false |
Reverses the rating direction for right-to-left layouts. |
onHover |
function(currentRating, selectedRating) |
— | Called while the pointer moves over the rater. |
onLeave |
function(currentRating, selectedRating) |
— | Called when the pointer leaves the rater. |
| Member | Description |
|---|---|
setRating(rating) |
Sets the current rating. The value must be a number between 0 and max. |
getRating() |
Returns the selected rating, or null when no rating is set. |
clear() |
Clears the selected rating and resets the visual value. |
disable() |
Prevents user interaction and applies the disabled state. |
enable() |
Restores user interaction. |
dispose() |
Removes the mouse and touch event handlers registered by the instance. |
element |
Returns the element used by the rater instance. |
The default CSS and SVG stars are injected at runtime. Override the background
images to use your own stars. Set starSize when the images should be displayed
at a size other than 16 pixels.
/* Image used for the unselected stars. */
.star-rating {
background-image: url("my-star-off.svg") !important;
}
/* Image used for the selected stars. */
.star-rating .star-value {
background-image: url("my-star-on.svg") !important;
}Want to contribute? Awesome! The most basic way to show your support is to star the project, or to raise issues. You can also support this project by becoming a sponsor on GitHub or by making a PayPal donation to ensure this journey continues indefinitely!
See CONTRIBUTING.md for how to set up a dev environment and submit a pull request.
Thanks again for your support, it is much appreciated! 🙏
Development and CI use Node.js 24. With nvm installed, select the configured version and run the build and test suite:
nvm use
npm ci
npm test
npm run test:packageVersion 2.0 is ESM-only. Replace CommonJS require calls with a default import:
- const raterJs = require("rater-js");
+ import raterJs from "rater-js";CommonJS and AMD loaders are no longer supported. For direct browser usage, replace the old root bundle with the standalone browser build:
- <script src="node_modules/rater-js/index.js"></script>
+ <script src="node_modules/rater-js/dist/rater-js.iife.min.js"></script>The browser global remains window.raterJs.
npm version patch|minor|major(bumps package.json, commits, tags locally)git push && git push --tags- Create a GitHub Release from the new tag (GitHub UI, or
gh release create vX.Y.Z --generate-notes)
Publishing to npm happens automatically via .github/workflows/release.yml once the Release is published. The workflow also attaches the ESM build, standalone browser build, and sourcemap to the GitHub Release.
rater-js is available under the MIT License.