Your activity data.
Beautifully presented.
Streakr renders contribution data from anywhere. You own acquisition, caching and credentials; Streakr owns the responsive heatmap, ring, filters and statistics.
Both layouts, side by side
The same component draws a 53-week heatmap in wide containers and a radial year ring under 520px — it switches on container width, not on user agent. Everything here is a real instance: toggle a source chip and the grid, the ring and the records recompute.
Any data. One shape.
Four numbers, computed for you
Streaks come out of the validated daily series, so they respect whichever sources are switched on. Select the current year and the card swaps Active Rate for Current Streak.
Data in. Calendar out.
Ships ESM plus one stylesheet with no CSS dependencies. Drop it into a bundler, or pull it straight off a CDN in a plain HTML file.
# install
npm install @rosado-io/streakr
// mount
import { createStreakr } from '@rosado-io/streakr'
import '@rosado-io/streakr/styles.css'
createStreakr({
target: document.querySelector('#streakr'),
theme: 'dark',
years: [2024, 2025, 2026],
days: activity,
})
Bring your data. Or borrow a recipe.
Recipes show one way to acquire and adapt data, but they stay in your application. Keep them, replace them, or connect your own API—the renderer only cares about its small serializable contract.
// recipe: adapt a public GitHub calendar response
const response = await fetch(
'https://github-contributions-api.jogruber.de/v4/octocat?y=2026'
)
const payload = await response.json()
const days = payload.contributions.map((day) => ({
date: day.date,
count: day.count,
sources: { github: day.count },
}))
createStreakr({
target: document.querySelector('#streakr'),
years: [2026],
days,
})
Put your year on the page.
Free, MIT and framework-free. Read the docs, or clone the repo and run the demo locally.