PassengerC07252 downloadsTrack your habits with visual progress and streaks.
An interactive habit tracking plugin for Obsidian with a Today view, monthly and yearly heatmap views, streak tracking (strict/forgiving), and multiple tracker support -- all powered by readable Markdown files.
Based on Obsidian-Tracker by Nodeencoder. This project extends and enhances the original with additional views, settings, and improved data management.
The following features are planned but not yet implemented:
Build the plugin:
npm install
npm run build
Copy the output to your Obsidian vault's plugins folder:
.obsidian/plugins/banshan-habit-tracker/
Enable the plugin in Settings -> Community plugins -> Turn on community plugins, then find and enable Banshan Habit Tracker.
Install dependencies:
npm install
Start the dev watch server:
npm run dev
Open your Obsidian vault and enable Banshan Habit Tracker from community plugins. The watch server will rebuild automatically on file changes.
Create a new Markdown note in your vault with YAML frontmatter and a markdown table:
---
name: "Fitness Tracker"
created: "2026-06-10"
habits:
- name: "Morning Run"
icon: "🏃"
frequency: "daily"
streakMode: "strict"
startDate: "2026-06-10"
- name: "Evening Stretch"
icon: "🧘"
frequency: "daily"
streakMode: "forgiving"
startDate: "2026-06-10"
- name: "Weight Lifting"
icon: "💪"
frequency: "specific"
specificDays: ["Mon", "Wed", "Fri"]
streakMode: "strict"
startDate: "2026-06-10"
---
| Habit | Mon 6/10 | Tue 6/11 | Wed 6/12 |
|-------|----------|----------|----------|
| 🏃 Morning Run | ✓ | | ✓ |
| 🧘 Evening Stretch | ✓ | ✓ | ✓ |
| 💪 Weight Lifting | ✓ | | ✓ |
Open the plugin -- Click the calendar ribbon icon in the left sidebar, or use the command palette (Ctrl+P / Cmd+P):
Habit Tracker: Open Habit TrackerTracker View -- A single tracker view with:
Adding Habits -- Click + Add Habit to create a new habit with name, icon, color (preset or custom), frequency, streak mode, and specific days.
| Field | Values | Description |
|---|---|---|
name |
Any string | Display name for the habit |
icon |
Any emoji | Visual icon shown in the UI |
frequency |
daily, weekly, specific |
How often the habit occurs |
specificDays |
["Mon", "Wed", "Fri"] |
Days of the week (used with specific frequency) |
streakMode |
strict, forgiving |
Strict: any missed day breaks streak. Forgiven: 1-day grace period allowed |
startDate |
YYYY-MM-DD |
When to start tracking |
| Symbol | Status |
|---|---|
✓ |
Completed |
✗ |
Missed |
| (empty) | Unmarked |
Obsidian-Habit-tracker/
├── src/
│ ├── main.ts # Plugin entry point, settings tab, commands
│ ├── view.ts # Custom Obsidian view with controls and view switching
│ ├── types.ts # TypeScript interfaces (Habit, Tracker, AppState, etc.)
│ ├── streak.ts # Streak calculation (strict & forgiving modes)
│ ├── parser.ts # YAML frontmatter + markdown table reader/writer
│ ├── store.ts # State management with habit actions
│ ├── styles.css # Plugin stylesheet
│ └── views/
│ ├── modals.ts # Add/Edit/Delete habit modals
│ ├── dashboard.ts # Dashboard summary and analytics rendering
│ ├── today.ts # Today view rendering
│ ├── month.ts # Month view rendering
│ ├── year.ts # Year heatmap view rendering
│ └── yearOverview.ts # Per-habit monthly overview rendering
├── tests/
│ ├── streak.test.ts # 6 tests for streak calculation
│ ├── parser.test.ts # 8 tests for YAML/table parsing & generation
│ └── store.test.ts # 5 tests for store actions
├── package.json
├── package-lock.json
├── tsconfig.json # TypeScript config
├── build.js # esbuild build script
├── vite.config.ts # Vite config (legacy)
├── vitest.config.ts # Vitest test config
└── manifest.json # Obsidian plugin manifest
Run all tests:
npm test
# or
npx vitest run
Run a specific test file:
npx vitest run streak
npx vitest run parser
npx vitest run store
Run tests in watch mode:
npx vitest
| Module | Tests | Description |
|---|---|---|
streak.test.ts |
6 | Current streak, longest streak, strict mode, forgiving mode, unmarked days, specific frequency filtering |
parser.test.ts |
8 | YAML parsing, table parsing, null handling, round-trip generation, column count |
store.test.ts |
5 | Toggle day, add habit, delete habit, heatmap view switching |
Total: 19 tests
| Script | Description |
|---|---|
npm run build |
Production build to .obsidian/plugins/banshan-habit-tracker/ |
npm run dev |
Watch mode -- rebuilds on file changes |
npm test |
Run all tests |
npm run test:watch |
Tests in watch mode |
npm run typecheck |
TypeScript type check only |
# Production build
npm run build
# TypeScript type check only
npm run typecheck
Output is placed in .obsidian/plugins/banshan-habit-tracker/:
main.js -- Bundled plugin codestyles.css -- Stylesheetmanifest.json -- Plugin manifest (copied from root)| Package | Purpose |
|---|---|
obsidian |
Obsidian API types (runtime) |
js-yaml |
YAML parsing/generation (runtime) |
| Package | Purpose |
|---|---|
esbuild ^0.20.0 |
Bundling and minification |
vitest ^1.0.0 |
Testing framework |
typescript ^5.3.0 |
Type checking |
.obsidian/plugins/banshan-habit-tracker/ and the plugin is enabled in settingshabits: in the YAML frontmatter and have .md extension