| name | habit-tracker |
| description | Self-hosted daily habit check-in app with streaks, calendar heatmap, and weekly email reports. Use when you need to record a habit check-in, query streak data, create or update habits, review weekly progress, or manage categories. Triggers include "log habit", "check in", "mark done", "streak", "habit progress", "weekly report", or any task involving personal habit tracking. |
habit-tracker
Track daily habits with streaks and visualizations. Self-hosted, no accounts.
When to use
- Recording a habit check-in for today or a past date
- Querying current streak or completion rate for a habit
- Creating, updating, or archiving habits
- Checking today's completion status
- Reviewing weekly progress
- Managing categories
- Sending or previewing the weekly email report
Base URL
http://localhost:3000
Configure with PORT env var if different.
Quick Reference
Check in a habit for today
curl -X POST http://localhost:3000/api/habits/1/checkin
Check in for a specific date
curl -X POST http://localhost:3000/api/habits/1/checkin \
-H "Content-Type: application/json" \
-d '{"date": "2026-03-15"}'
Uncheck a habit
curl -X DELETE http://localhost:3000/api/habits/1/checkin \
-H "Content-Type: application/json" \
-d '{"date": "2026-03-20"}'
List today's habits with status
curl http://localhost:3000/api/habits
Get a single habit with stats
curl http://localhost:3000/api/habits/1
Create a habit
curl -X POST http://localhost:3000/api/habits \
-H "Content-Type: application/json" \
-d '{
"name": "Morning run",
"description": "5km before 8am",
"categoryId": 1,
"frequency": "daily",
"color": "#ef4444"
}'
Archive a habit
curl -X PATCH http://localhost:3000/api/habits/1/archive
Get overall stats
curl http://localhost:3000/api/stats
Trigger weekly report email
curl -X POST http://localhost:3000/api/email/report
Send test email
curl -X POST http://localhost:3000/api/email/test
API Reference
Habits
| Method | Path | Description |
|---|
| GET | /api/habits | List habits with today's status |
| GET | /api/habits/:id | Single habit + stats |
| POST | /api/habits | Create habit |
| PUT | /api/habits/:id | Update habit |
| DELETE | /api/habits/:id | Delete habit and all check-ins |
| PATCH | /api/habits/:id/archive | Toggle archived state |
Query params for GET /api/habits:
archived=true - include archived habits
category=<id> - filter by category
date=YYYY-MM-DD - compute completion for specific date
Check-ins
| Method | Path | Description |
|---|
| POST | /api/habits/:id/checkin | Mark done (body: { date?: string }) |
| DELETE | /api/habits/:id/checkin | Unmark (body: { date: string }) |
| GET | /api/habits/:id/checkins | History (query: from, to, limit) |
| GET | /api/habits/:id/heatmap | 365-day heatmap data |
Categories
| Method | Path | Description |
|---|
| GET | /api/categories | List all categories |
| POST | /api/categories | Create category |
| PUT | /api/categories/:id | Update category |
| DELETE | /api/categories/:id | Delete category |
Stats and Settings
| Method | Path | Description |
|---|
| GET | /api/stats | Overview stats |
| GET | /api/stats/weekly | Per-habit weekly breakdown |
| GET | /api/settings | All settings |
| PATCH | /api/settings | Update settings |
| POST | /api/email/test | Send test email |
| POST | /api/email/report | Trigger weekly report now |
Habit Object
{
id: number
name: string
description: string | null
category: { id: number; name: string; color: string } | null
frequency: "daily" | "weekdays" | "weekends" | "custom"
customDays: number[] | null
color: string
isArchived: boolean
currentStreak: number
longestStreak: number
completedToday: boolean
totalCheckins: number
createdAt: string
}
Environment Variables
| Variable | Description | Default |
|---|
| PORT | Server port | 3000 |
| DATA_DIR | Directory for SQLite file | ./data |
| DATABASE_PATH | Full SQLite path (overrides DATA_DIR) | - |
| SMTP_HOST | SMTP server | - |
| SMTP_PORT | SMTP port | 587 |
| SMTP_SECURE | Use TLS: 0 or 1 | 0 |
| SMTP_USER | SMTP username | - |
| SMTP_PASS | SMTP password | - |
| SMTP_FROM | From address | habit-tracker@localhost |
| REPORT_TO | Weekly report recipient | - |
| TIMEZONE | Timezone for date logic | UTC |
| LOG_LEVEL | debug/info/warn/error | info |
Frequency Values
| Value | Description |
|---|
daily | Every day |
weekdays | Monday-Friday only |
weekends | Saturday-Sunday only |
custom | Specific days in customDays array |
Streak Rules
- Current streak: consecutive days ending today (or yesterday if today not yet checked)
- Gap of 2+ days resets streak to 0
- Weekend days ignored for weekday habits; weekdays ignored for weekend habits
- Streaks are computed fresh on every habit fetch - not cached