GitHub

Streak Calendar

React streak calendar for gamification—week, month, and git-style grids to visualize consistency. Native support for streak freezes. Ideal streak UI design for habit tracking and personal progress. Built on shadcn/ui and Tailwind CSS. Open source.

The Streak Calendar is a flexible gamification component for visualizing streak consistency with active days, weeks, and months with native support for streak freezes in retention-focused gamification UIs. Compose with Streak Badge or Streak Card when you need streak gamification UI at scale.

Sun
Mon
Tue
Wed
Thu
Fri
Sat

Installation

npx shadcn@latest add https://ui.trophy.so/streak-calendar

Usage

Import the component:

import { StreakCalendar } from "@/components/ui/streak-calendar"

Examples

Basic Usage

Sun
Mon
Tue
Wed
Thu
Fri
Sat
const streak = [
  { periodStart: "2024-01-01", periodEnd: "2024-01-01" },
  { periodStart: "2024-01-02", periodEnd: "2024-01-02" },
  { periodStart: "2024-01-03", periodEnd: "2024-01-03" },
]

<StreakCalendar streak={streak} />

Monday Start

Mon
Tue
Wed
Thu
Fri
Sat
Sun
const streak = [
  { periodStart: "2024-01-01", periodEnd: "2024-01-01" },
  { periodStart: "2024-01-02", periodEnd: "2024-01-02" },
  { periodStart: "2024-01-03", periodEnd: "2024-01-03" },
]

<StreakCalendar streak={streak} startOfWeek={1} />

Month View

May 2026

Su
Mo
Tu
We
Th
Fr
Sa
const streak = [
  { periodStart: "2024-01-01", periodEnd: "2024-01-01" },
  { periodStart: "2024-01-02", periodEnd: "2024-01-02" },
  { periodStart: "2024-01-03", periodEnd: "2024-01-03" },
]

<StreakCalendar
  streak={streak}
  view="month"
  month={new Date(2024, 0, 1)}
/>

Git-Style Year View

Last 365 days

Ending May 15

const streak = [
  { periodStart: "2024-01-01", periodEnd: "2024-01-01" },
  { periodStart: "2024-01-02", periodEnd: "2024-01-02" },
  { periodStart: "2024-01-03", periodEnd: "2024-01-03" },
]

<StreakCalendar
  streak={streak}
  view="year"
/>

With Freezes

Sun
Mon
Tue
Wed
Thu
Fri
Sat
const streak = [
  { periodStart: "2024-01-01", periodEnd: "2024-01-01" },
  { periodStart: "2024-01-02", periodEnd: "2024-01-02" },
  { periodStart: "2024-01-04", periodEnd: "2024-01-04", usedFreeze: true },
]

<StreakCalendar streak={streak} />

With Trophy

Use the Trophy SDK to fetch streak data server-side:

import { TrophyApiClient } from '@trophyso/node';

const trophy = new TrophyApiClient({
  apiKey: 'YOUR_API_KEY'
});

const response = await trophy.users.streak("user-id", {
  historyPeriods: 14
});

Then pass the response into StreakCalendar props in your UI layer:

<StreakCalendar streak={response.streakHistory} />

API Reference

Props

PropTypeDefaultDescription
streakStreakPeriod[]RequiredStreak data as periods array
view"week" | "month" | "year""week"Calendar layout style
monthDateCurrent monthMonth to display
referenceDateDateTodayAnchor date for week view
showFreezesbooleantrueShow freeze indicators on days
startOfWeek0 | 10Week start: 0 = Sunday, 1 = Monday
onDayClick(date: Date, wasActive: boolean) => void-Callback when day is clicked

Types

interface StreakPeriod {
  periodStart: string
  periodEnd: string
  usedFreeze?: boolean
}