Retention cohorts
@usagemetrics/retention-cohorts
Build weekly or monthly retention cohorts for users or accounts from an events CSV. Writes the cohort table, a size-weighted average curve, where the curve flattens, and the best and worst cohorts, as markdown, CSV, and JSON.
- Activity
- New: be the first to try it
- Installs
- 0 installs
- Likes
- 0 likes
- Clones
- 0 clones
- 1{
- 2 "name": "retention-cohorts",
- 3 "owner": "usagemetrics",
- 4 "version": "1.0.0",
- 5 "type": "skill",
- 6 "description": "Build weekly or monthly retention cohorts for users or accounts from an events CSV. Writes the cohort table, a size-weighted average curve, where the curve flattens, and the best and worst cohorts, as markdown, CSV, and JSON.",
- 7 "category": "data",
- 8 "license": "MIT",
- 9 "compat": ["claude-code"],
- 10 "permissions": {
- 11 "shell": ["node scripts/cohorts.mjs"],
- 12 "files": { "read": ["./data/**"], "write": ["./out/retention*"] }
- 13 },
- 14 "tests": {
- 15 "cases": [
- 16 {
- 17 "name": "monthly user cohorts from the example events",
- 18 "inputs": {},
- 19 "checks": [
- 20 { "type": "command_exits_zero", "command": "node scripts/cohorts.mjs examples/events.csv --period month --entity user --out out/retention" },
- 21 { "type": "file_exists", "path": "out/retention.csv" },
- 22 { "type": "file_contains", "path": "out/retention.md", "text": "| 2025-11 | 11 | 100% | 27% |" },
- 23 {
- 24 "type": "output_matches_schema",
- 25 "path": "out/retention.json",
- 26 "schema": {
- 27 "type": "object",
- 28 "required": ["cohorts", "average_curve", "best_period1", "worst_period1"],
- 29 "properties": {
- 30 "last_complete_period": { "const": "2026-09" },
- 31 "cohorts": { "type": "array", "minItems": 11, "maxItems": 11 },
- 32 "best_period1": { "type": "object", "properties": { "cohort": { "const": "2026-06" } } },
- 33 "worst_period1": { "type": "object", "properties": { "cohort": { "const": "2025-11" } } }
- 34 }
- 35 }
- 36 }
- 37 ]
- 38 },
- 39 {
- 40 "name": "only counts the chosen active events and leaves out the current month",
- 41 "inputs": {
- 42 "data/events.csv": "timestamp,account_id,user_id,event\n2026-01-05,a1,u1,ran_query\n2026-01-09,a1,u2,ran_query\n2026-02-03,a1,u1,login\n2026-02-10,a1,u2,ran_query\n2026-02-11,a2,u3,ran_query\n2026-03-02,a2,u3,ran_query\n"
- 43 },
- 44 "checks": [
- 45 { "type": "command_exits_zero", "command": "node scripts/cohorts.mjs data/events.csv --active-events ran_query --out out/retention" },
- 46 {
- 47 "type": "output_matches_schema",
- 48 "path": "out/retention.json",
- 49 "schema": {
- 50 "type": "object",
- 51 "properties": {
- 52 "last_complete_period": { "const": "2026-02" },
- 53 "cohorts": {
- 54 "type": "array",
- 55 "minItems": 2,
- 56 "maxItems": 2,
- 57 "items": { "type": "object", "required": ["cohort", "size", "rates"] }
- 58 },
- 59 "average_curve": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "type": "object" } }
- 60 }
- 61 }
- 62 },
- 63 { "type": "file_contains", "path": "out/retention.md", "text": "| 2026-01 | 2 | 100% | 50% |" }
- 64 ]
- 65 }
- 66 ]
- 67 }
- 68}
