Cohort Retention
The retention triangle: cohorts down, periods across, intensity by share retained, with a row and column crosshair and a period average.
Monthly cohorts
@spectrumui/cohort-chart
Signup cohort retention
12 cohorts · 14.5K users
Month 1 avg 61.7%
| Cohort | Users | Month 0 | Month 1 | Month 2 | Month 3 | Month 4 | Month 5 | Month 6 | Month 7 | Month 8 | Month 9 | Month 10 | Month 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Sep 2025 | 674 | 100.0% | 60.8% | 58.7% | 53.5% | 51.0% | 47.3% | 42.8% | 39.0% | 37.7% | 36.0% | 34.7% | 33.2% |
| Oct 2025 | 1150 | 100.0% | 62.7% | 61.1% | 56.6% | 54.1% | 50.9% | 48.0% | 45.2% | 42.7% | 41.9% | 38.5% | — |
| Nov 2025 | 764 | 100.0% | 55.6% | 54.3% | 52.6% | 51.0% | 47.8% | 46.9% | 45.5% | 43.5% | 42.6% | — | — |
| Dec 2025 | 855 | 100.0% | 63.7% | 63.2% | 62.9% | 59.0% | 58.3% | 54.4% | 53.9% | 52.1% | — | — | — |
| Jan 2026 | 1245 | 100.0% | 66.4% | 66.1% | 62.8% | 61.5% | 59.1% | 56.1% | 55.8% | — | — | — | — |
| Feb 2026 | 1566 | 100.0% | 64.5% | 63.3% | 62.9% | 62.2% | 59.6% | 57.8% | — | — | — | — | — |
| Mar 2026 | 1450 | 100.0% | 65.3% | 65.0% | 64.6% | 64.3% | 62.1% | — | — | — | — | — | — |
| Apr 2026 | 1021 | 100.0% | 63.7% | 63.3% | 63.0% | 62.1% | — | — | — | — | — | — | — |
| May 2026 | 1538 | 100.0% | 59.1% | 58.8% | 58.5% | — | — | — | — | — | — | — | — |
| Jun 2026 | 1207 | 100.0% | 58.0% | 57.7% | — | — | — | — | — | — | — | — | — |
| Jul 2026 | 1781 | 100.0% | 59.1% | — | — | — | — | — | — | — | — | — | — |
| Aug 2026 | 1290 | 100.0% | — | — | — | — | — | — | — | — | — | — | — |
Login to view codeCreate a free account to access component source code
Login to view codeCreate a free account to access component source code
Login to view codeCreate a free account to access component source code
Weekly activation
Weekly activation cohorts
12 cohorts · 14.5K users
Week 1 avg 60.9%
| Cohort | Users | Week 0 | Week 1 | Week 2 | Week 3 | Week 4 | Week 5 | Week 6 | Week 7 | Week 8 | Week 9 | Week 10 | Week 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Sep 2025 | 1045 | 100.0% | 54.5% | 51.3% | 49.0% | 46.1% | 41.5% | 37.9% | 36.1% | 35.0% | 32.2% | 31.1% | 29.9% |
| Oct 2025 | 582 | 100.0% | 61.0% | 56.8% | 55.2% | 52.3% | 49.5% | 47.6% | 46.4% | 45.1% | 43.6% | 42.3% | — |
| Nov 2025 | 591 | 100.0% | 60.2% | 58.5% | 58.0% | 55.7% | 54.7% | 53.2% | 52.2% | 49.0% | 46.2% | — | — |
| Dec 2025 | 1440 | 100.0% | 60.5% | 56.8% | 53.9% | 53.0% | 52.7% | 52.1% | 49.8% | 47.5% | — | — | — |
| Jan 2026 | 902 | 100.0% | 59.3% | 56.4% | 54.3% | 52.0% | 51.7% | 49.2% | 46.4% | — | — | — | — |
| Feb 2026 | 1639 | 100.0% | 60.9% | 58.9% | 58.6% | 58.3% | 57.8% | 56.9% | — | — | — | — | — |
| Mar 2026 | 1073 | 100.0% | 59.8% | 59.5% | 58.9% | 58.1% | 57.8% | — | — | — | — | — | — |
| Apr 2026 | 1652 | 100.0% | 64.3% | 64.0% | 63.6% | 63.3% | — | — | — | — | — | — | — |
| May 2026 | 1223 | 100.0% | 64.5% | 64.2% | 63.8% | — | — | — | — | — | — | — | — |
| Jun 2026 | 1280 | 100.0% | 58.8% | 58.5% | — | — | — | — | — | — | — | — | — |
| Jul 2026 | 1655 | 100.0% | 66.3% | — | — | — | — | — | — | — | — | — | — |
| Aug 2026 | 1446 | 100.0% | — | — | — | — | — | — | — | — | — | — | — |
Login to view codeCreate a free account to access component source code
Login to view codeCreate a free account to access component source code
Login to view codeCreate a free account to access component source code
Manual installation
Prefer to copy by hand? Open the Code tab on any example above and switch to the file you need — every source file is there, not just the demo. Drop them in your project like this:
chart-engine.tsxcomponents/spectrumui/charts/chart-engine.tsxcohort-chart.tsxcomponents/spectrumui/charts/cohort-chart.tsx
There is nothing to install — this chart draws its own SVG and imports only @/lib/utils.
Usage
import { CohortChart } from '@/components/spectrumui/charts/cohort-chart';
<CohortChart data={cohorts} period="Month" />- Give later cohorts shorter
retentionarrays — the ragged edge is the point. - Index 0 should always be 100; the chart does not normalise for you.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | Cohort[] | COHORTS | Each cohort needs a label, a size, and a retention array starting at 100. |
period | string | 'Month' | Column heading prefix — Month, Week or Day. |
label | string | - | Header title. |
hue | string | series-1 | CSS colour for the intensity ramp. |
status | 'ready' | 'loading' | 'empty' | 'error' | 'ready' | Which state to render. All four reserve the same frame height, so nothing shifts when data lands. |
onRetry | () => void | - | Called by the retry button in the error state. Omit it and no button is shown. |
className | string | - | Merged onto the root element. |