@animesh0764/contribution-graph
v0.1.0
Published
GitHub-style contribution graphs for any application — no dependencies, TypeScript-first
Maintainers
Readme
contribution-graph
GitHub-style contribution graphs for any application. No dependencies. TypeScript-first.
Install
npm install @animesh0764/contribution-graphQuick start
Core (framework-agnostic)
import { buildContributionGraph } from '@animesh0764/contribution-graph'
const data = buildContributionGraph([
'2026-01-15',
'2026-01-16',
{ date: '2026-01-17', count: 5 },
])
console.log(data.stats.currentStreak) // number
console.log(data.stats.totalContributions) // numberReact component
import { buildContributionGraph } from '@animesh0764/contribution-graph'
import { ContributionGraph } from '@animesh0764/contribution-graph/react'
const data = buildContributionGraph(events)
<ContributionGraph data={data} theme="github-dark" />API
buildContributionGraph(events, options?)
| Parameter | Type | Description |
|-----------|------|-------------|
| events | ContributionInput[] | Activity data. Strings (YYYY-MM-DD), Date objects, or { date, count } objects. |
| options | ContributionOptions | Optional config (see below). |
Returns ContributionGraphData:
| Field | Type | Description |
|-------|------|-------------|
| cells | ContributionCell[] | One entry per calendar day in the range (including padding days). |
| weeks | ContributionWeek[] | Cells grouped into week columns (ready for rendering). |
| monthLabels | MonthLabel[] | Month name + grid column index for positioning labels. |
| stats | ContributionStats | Aggregated statistics (see below). |
| from | string | Actual aligned start date (YYYY-MM-DD). |
| to | string | End date used (YYYY-MM-DD). |
| weekStartsOn | 0 \| 1 | 0 = Sunday, 1 = Monday. |
Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| from | string | 364 days before to | Start of the date range (YYYY-MM-DD). |
| to | string | today | End of the date range (YYYY-MM-DD). |
| timezone | string | system local | IANA timezone e.g. 'America/New_York'. |
| weekStartsOn | 0 \| 1 | 0 | 0 = Sunday (GitHub default), 1 = Monday. |
ContributionStats
| Field | Type | Description |
|-------|------|-------------|
| totalContributions | number | Sum of all activity counts in range. |
| activeDays | number | Days with at least one contribution. |
| currentStreak | number | Consecutive days ending today (or yesterday). |
| longestStreak | number | Longest streak of consecutive active days. |
| mostActiveDate | string \| null | Date with the highest single-day count. |
| mostActiveCount | number | Count on the most active day. |
| weeklyAverage | number | Average contributions per week over the range. |
| monthlyBreakdown | MonthBreakdown[] | Per-month totals and active day counts. |
ContributionCell
| Field | Type | Description |
|-------|------|-------------|
| date | string | YYYY-MM-DD. |
| count | number | Activity count for this day. |
| level | 0–4 | Intensity level (0 = no activity, 4 = highest quartile). |
| weekIndex | number | Column index in the grid. |
| dayOfWeek | number | Row index (0 = first day of week). |
| isOutOfRange | boolean | true for padding cells outside [from, to]. |
React component
import { ContributionGraph } from '@animesh0764/contribution-graph/react'
<ContributionGraph
data={data}
theme="github" // or "github-dark" or a custom theme object
blockSize={12} // px, default 12
blockGap={3} // px, default 3
showMonthLabels={true}
showWeekdayLabels={true}
showTooltip={true}
onDayClick={(cell) => console.log(cell)}
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | ContributionGraphData | — | Output from buildContributionGraph. |
| theme | 'github' \| 'github-dark' \| ContributionTheme | 'github' | Color theme. |
| blockSize | number | 12 | Size of each day square in px. |
| blockGap | number | 3 | Gap between squares in px. |
| showMonthLabels | boolean | true | Show month names above the grid. |
| showWeekdayLabels | boolean | true | Show Mon/Wed/Fri labels on the left. |
| showTooltip | boolean | true | Show hover tooltip with date + count. |
| onDayClick | (cell: ContributionCell) => void | — | Click handler for day cells. |
| style | CSSProperties | — | Inline styles for the container. |
| className | string | — | CSS class for the container. |
Custom theme
import type { ContributionTheme } from '@animesh0764/contribution-graph'
const myTheme: ContributionTheme = {
level0: '#f0f0f0',
level1: '#c6e8ff',
level2: '#79c9ff',
level3: '#1e9cff',
level4: '#0065cc',
background: '#ffffff',
text: '#333333',
}Intensity levels
Activity intensity is computed using a quartile distribution across the active days in your range. This means the colour scale adapts to your data volume: someone who makes 1–5 contributions/day gets the same visual spread as someone who makes 100+/day.
- Level 0 — no activity
- Level 1 — bottom 25% of active days
- Level 2 — 25th–50th percentile
- Level 3 — 50th–75th percentile
- Level 4 — top 25%
License
MIT
