Component reference

Star History

Stargazers over time, with annotated spikes.

Sample data · GitHub hides stargazers
Star history · lumen10,945
ada-dev/lumen went from 1 star on Oct 1, 2024 to 10,945 on Sep 30, 2026. Jul 14, 2025: hit the HN front page! (2,139 stars).
<StarHistory variant="minimal" />Clean surfaces and measured motion.

Installation

Use the shadcn CLI to copy the component source and its dependencies into your own project. Installs motion and @number-flow/react, plus the Ovio theme, world, motion, rolling-number, keys, format items.

npx shadcn add JanaSundar/ovio/star-history
↳You own the source. Ovio components arrive in your codebase so you can edit any part of their style, behavior, or data flow.

Usage

Set the visual world on the component, or wrap the page in an OvioProvider to set a default for everything inside it.

TSXvariant="minimal"
import { StarHistory } from "@/components/ovio/star-history/star-history"

<StarHistory
  variant="minimal"
  data={stars}
/>

Built with: SVG · Motion for React path draw
Motion in Minimal: Small springs, opacity and layout shifts that show state.

Data

Fetch it on the server with getStarHistory("owner/name") and pass the result as props. The helper is lib/github.ts, added with the CLI.

npx shadcn add JanaSundar/ovio/github
SourceGitHub's REST API: stargazers with the time each star was given.
AuthThe repository owner's token. GitHub lists stargazers only to the owner, so you can chart your own repos but not someone else's.
LimitsUp to 16 requests per refresh: the repo, then 15 pages of 100 stargazers, sampled evenly. GitHub serves at most 400 pages.
CachingCached for an hour by default (revalidate: 3600), so traffic adds no API calls. A failed refresh keeps serving the last good data, and a spent limit throws RateLimitError with the time it resets.
This demoSample data: GitHub hides stargazers.

Props

Control the data, selected world, animation behavior, and callbacks.

PropTypeDescription
data{ date: string; stars: number }[]Cumulative stars by day, any order.
repostring"owner/name", for the title and accessible name.
annotations{ date; label }[]Callouts on the curve.
variant| "minimal" | "craft" | "retro" | "toy"Which world to render. Defaults to the nearest OvioProvider, then minimal.
animation| "none" | "enter-exit" | "always"Default "enter-exit". "always" keeps a live marker on the latest point. Forced to "none" under reduced motion.
classNamestringMerged onto the root.