Developers

Reviews that don't cost you your Core Web Vitals

A full product-page reviews widget in about 27 KB over the wire. Nothing blocks rendering. Nothing moves once it arrives. Every element restyles with plain CSS.

27 KB

Brotli, product page. Stars, reviews, styles and translations.

0.002

Cumulative Layout Shift. Google's "good" threshold is 0.1.

0

Render-blocking scripts. Every tag ships defer.

Roughly a sixth of what the category ships

Every reviews app puts a script on your product page. Here is what each one costs a shopper, compressed the way a browser actually receives it.

Classic Ratings ~27 KB
Stamped ~49 KB
Judge.me ~161 KB
Okendo ~300 KB

Measured August 2026 by fetching each vendor's product-page review bundle straight from their CDN with brotli requested. Okendo is the gzip figure, because they do not serve brotli. Loox is not listed: their bundle is not fetchable without a live store. Your own numbers will vary with the blocks you enable.

What happens on a product page

The page paints before we run. When our content arrives it lands in space that was already reserved for it, so nothing jumps.

Load sequence: the page paints first, then deferred scripts run, then content fills reserved space BROWSER CLASSIC RATINGS SHOPPER SEES Parse HTML Our tags are deferred First paint Product page is usable Scripts execute ~27 KB, after DOM ready One request per widget ~7 KB of JSON, cached after Space reserved for reviews Reviews fill it. Nothing moves.

Deferred, never blocking

Every script tag we emit carries defer. Your theme paints on its own schedule and we run afterwards.

Space held with real markup

The placeholder is the actual review row made invisible, not a guessed skeleton box, so its height is right by construction and the price below never jumps.

Ratings cached across the session

Star ratings persist in localStorage, so collection page to product page to related products refetches nothing.

Restyle it with CSS you already know

No proprietary theming layer, no build step, no support ticket. Every widget exposes custom properties and stable class names.

Custom properties for the common cases

/* Anywhere in your theme's stylesheet */
.cr-reviews {
  --cr-star-color: #b45309;
  --cr-text-color: #1f2937;
  --cr-border-color: #e5e7eb;
  --cr-button-bg: #111827;
  --cr-button-text: #ffffff;
  --cr-button-radius: 2px;
}

Around 128 properties across the widgets, all listed in the reference below.

Or target the elements directly

/* Class names are stable and namespaced */
.cr-review {
  border: 0;
  border-bottom: 1px solid #eee;
}

.cr-review-author {
  font-family: var(--font-heading);
  letter-spacing: 0.02em;
}

.cr-rating-summary { gap: 3rem; }

Every class is prefixed cr-, so nothing collides with your theme.

You will not need !important

Widget tokens are written to a stylesheet rule keyed on the block's id using the attribute form, [id="cr-x"], rather than #cr-x. An id selector scores (1,0,0) and would beat anything you write. The attribute form scores (0,1,0), so a single-class rule of yours ties on specificity and wins on document order.

The low specificity is deliberate. It is the whole reason overriding our styles is boring.

Reference

Try it on a real theme

Free plan, no card. Add the blocks in your theme editor and measure it yourself.

Install Classic Ratings