React best practices, with barely any JavaScript

A growing collection of recipes done with pure CSS or a single delegated listener. Scroll down — everything you see below runs on the platform.

recipe 01

fit-text

The font scales to its container with container-query units — no measuring, no layout shift. Drag the handle and watch it rescale live (shadcn Resizable).

Learn anything
← drag to resize

recipe 02

parallax

Each frame holds a layer that drifts at its own rate as you scroll — depth rendered on the compositor (animation-timeline: view()), no scroll listener.

depth from scroll

Nine layers, nine speeds

Every blob, ring and dot rides its own view() timeline. Nothing here listens to scroll.

stagger — the same recipe over a group; each child's entrance is offset from the last.

recipe 03

reveal

Each card fades and rises into place as it enters the viewport — a view() timeline, no IntersectionObserver.

Zero client JS

Recipes lean on CSS and the platform, not hooks.

Correct on first paint

No measure-then-resize, no post-mount jump.

RSC-safe

Components stay server HTML — no "use client".

Graceful fallback

Unsupported browsers just render at rest.

Reduced-motion aware

Animations bow out when the user asks.

Tiny

Each recipe is a few lines of CSS + a thin wrapper.

recipe 04

accordion

Native <details> with a smooth interpolate-size open/close. Exclusive (only one open) via a shared name — no state.

Does this ship JavaScript?

Almost none. fit-text, parallax, reveal and accordion are pure CSS; analytics is a single delegated listener for the whole app.

Do the components need "use client"?

No. They only render markup and set CSS variables / data attributes, so they work as Server Components.

What about old browsers?

Every recipe is gated behind @supports or native fallbacks — unsupported engines render the content at rest, never broken.

Can I use one recipe only?

Yes — each is its own subpath import, so you ship only what you use.

recipe 05

analytics

These buttons are plain server HTML with data-track attributes. One delegated listener (in instrumentation-client.ts) catches every click — a toast pops up for each event.

recipe 06

scroll-progress

The emerald bar pinned to the very top of this page is the scroll-progress recipe — one fixed element whose scaleX rides the document's scroll() timeline. Scroll and watch it fill; no listener.

recipe 07

sticky-shrink

Scroll inside the box — the header shrinks from 96 to 56px over the first 180px, driven by one registered progress var. The logo reads that same var and scales in step. Zero JS.

Acme

Row 1 — keep scrolling to shrink the header above.

Row 2 — keep scrolling to shrink the header above.

Row 3 — keep scrolling to shrink the header above.

Row 4 — keep scrolling to shrink the header above.

Row 5 — keep scrolling to shrink the header above.

Row 6 — keep scrolling to shrink the header above.

Row 7 — keep scrolling to shrink the header above.

Row 8 — keep scrolling to shrink the header above.

Row 9 — keep scrolling to shrink the header above.

Row 10 — keep scrolling to shrink the header above.

Row 11 — keep scrolling to shrink the header above.

Row 12 — keep scrolling to shrink the header above.

Row 13 — keep scrolling to shrink the header above.

Row 14 — keep scrolling to shrink the header above.

recipe 08

slider

A CSS scroll-snap track — swipe or trackpad works everywhere. Dots and prev/next buttons are CSS Carousel pseudo-elements, so they need no JS. One slide at a time with a peek of the next; the arrow advances exactly one. (For a multi-slide row, use a smaller itemSize — the arrows then page the group, which is how scroll-buttons work. Controls want Chrome 135+.)

  • One
  • Two
  • Three
  • Four
  • Five

recipe 09

dialog

A native <dialog> opened by the HTML invoker commands (command="show-modal") — modal, backdrop, Esc, and backdrop-click to close (closedby="any") all native. Zero JS, no onClick. Needs Chrome 135+.

Native dialog

Opened and closed with zero JavaScript — the browser handles the modal, backdrop, Esc and focus. The animation is pure CSS (@starting-style).

recipe 10

popover

A native popover (menu / dropdown) via the Popover API — toggle, click-outside dismiss and the top layer are native, and it auto-anchors to the button with CSS anchor positioning. Zero JS. Needs Chrome 125+.