A modern, lightweight habit tracker built with vanilla HTML, CSS, and JavaScript.
- Create & Manage Habits - Add daily habits with specific times
- Daily Checklist - Mark habits complete each day
- Streak Tracking - Visual streak counter that encourages consistency
- Monthly Heatmap - See your progress at a glance
- Motivational Messages - Context-aware support that encourages without shaming
- Offline-First - Works completely offline with localStorage
- Mobile & Smartwatch Friendly - Responsive design for all devices including circular smartwatches
- Hamburger Menu - Settings accessible from top navigation
- Professional - Clean, modern SaaS-inspired interface
- Minimal - Focused, distraction-free experience
- Lightweight - Zero dependencies, pure JavaScript
- Persistent - All data saved locally to your browser
- Accessible - WCAG-compliant with keyboard navigation and reduced motion support
habbyt/
├── index.html # HTML structure and components
├── styles.css # Complete design system and layout
├── app.js # Main application controller
├── utils.js # Utilities for dates, storage, streaks
├── quotes.js # Motivational quote system
└── README.md # This file
{
habits: [
{
id: "habit_1234_xyz",
name: "Morning Run",
time: "06:00",
frequency: "daily",
createdDate: "2026-01-24"
}
],
completionHistory: {
"2026-01-24": ["habit_1234_xyz"],
"2026-01-23": ["habit_1234_xyz"],
// ...
},
lastLoadDate: "2026-01-24"
}Handles all localStorage operations:
initStorage()- Initialize app dataaddHabit(habit)- Create new habitcompleteHabit(habitId, date)- Mark completegetHabitStats(habitId)- Get streak/completion dataexportData()/importData()- Backup/restore
Calculates streak metrics:
calculateCurrentStreak(habitId)- Count consecutive dayscalculateBestStreak(habitId)- Find longest streakisMilestone(streak)- Detect milestone achievements (5, 10, 20, 30+ days)
All date operations:
today()- Get today's dateformatDate(date)- Convert to YYYY-MM-DDgetDatesInMonth(year, month)- Get all dates in a monthtoReadable(dateStr)- Human-readable format
Context-aware motivational messages:
getMorningQuote()- Start of daygetCompletionQuote()- After completing a habitgetStreakQuote(streak)- Milestone achievementsgetMissedQuote()- Compassionate support when streak breaks
Main application controller:
init()- Bootstrap appaddHabit()- User-facing add habittoggleHabit(habitId)- Mark complete/incompleterender()- Update all UIrenderMonthlyView()- Show heatmap
No build process needed! Just open index.html in your browser.
# Option 1: Direct file
open index.html
# Option 2: Local server (Python 3)
python3 -m http.server 8000
# Then visit http://localhost:8000
# Option 3: Local server (Node.js)
npx http-server- Add a Habit - Enter name, select time, click "Add Habit"
- Check Off Daily - Click checkbox to mark complete
- Track Progress - View streaks, stats, and monthly heatmap
- Get Motivated - Read supportive quotes that celebrate consistency
- Checklist automatically resets each day
- Data persists across browser sessions
- Streaks continue if you complete a habit on consecutive days
- Current streak: Consecutive days (including today if completed)
- Best streak: Longest consecutive days in history
- Streak breaks: Only when a day is completely missed
- Milestone quotes: Shown at 5, 10, 20, 30+ day streaks
Morning: Inspiring start-of-day messages Completion: Celebrate each habit completion Streak: Milestone achievements (every 5/10/20/30+ days) Missed: Compassionate support when streak breaks
All quotes are designed to:
- Celebrate progress
- Encourage growth
- Support setbacks
- Never shame or guilt
- Primary: Blue (#3b82f6) - Professional & trustworthy
- Primary Light: Light Blue (#60a5fa)
- Primary Dark: Dark Blue (#1e40af)
- Secondary: Emerald (#10b981) - Success & growth
- Accent: Amber (#f59e0b) - Highlights & CTAs
- Success: Emerald (#10b981) - Completion confirmation
- Heat Colors: Gray to Blue gradient - Activity levels
- Font: System stack (SF Pro Display, Segoe UI, etc.)
- Scale: 0.875rem to 2.5rem
- Weights: 300-700
- xs: 0.25rem
- sm: 0.5rem
- md: 1rem
- lg: 1.5rem
- xl: 2rem
- 2xl: 3rem
- Desktop: Full layout with 70% width container
- Tablet (768px): Adjusted spacing, touch-friendly
- Mobile (480px): Optimized for smaller screens
- Smartwatch (500px and below): Reduced fonts, compact spacing
- Circular Smartwatch (350px and below): Circular modal design, minimal interface
- 100% Client-Side: All data stored in browser's localStorage
- No Cloud: No tracking, no servers, no external APIs
- Offline-First: Works completely offline after first load
- Portable: Export data as JSON anytime
Data is stored in JSON format under key habbyt_data:
localStorage.getItem("habbyt_data");
// Returns: {"habits": [...], "completionHistory": {...}, "lastLoadDate": "..."}- Each day shows as a cell in a 7-column grid (Sunday-Saturday)
- Color indicates completion status:
- Gray: No habits completed
- Blue: All habits completed for that day
- Month navigation with previous/next buttons
- Habits stack vertically below the heatmap on the same page
- Day 1 - Create habit "Morning Walk" at 6:00 AM
- Day 1 - Check off at 7:00 AM - See encouragement quote
- Day 2 - Check off - Streak: 2 days
- Day 5 - Check off - Milestone quote!
- Day 6 - Miss day - Compassionate quote + encouragement to restart
- Day 7 - Check off - Back on track!
- View Month - See heatmap showing pattern with gray and blue cells
- Zero Dependencies: No npm packages needed
- Tiny Bundle: ~25KB uncompressed (HTML + CSS + JS)
- Instant Load: No build process, no bundling
- Smooth Animations: GPU-accelerated CSS transitions
- Battery Efficient: Minimal JavaScript execution
Edit :root variables in styles.css:
:root {
--color-primary: #3b82f6; /* Change to your color */
--color-secondary: #10b981;
/* ... */
}Edit quotes.js - add entries to QUOTES object:
morning: [
{ text: "Your custom quote here", author: "Attribution" },
// ...
];All dates handled by DateUtils - centralized for easy changes
Data not saving?
- Check browser allows localStorage (Settings > Privacy)
- Ensure you're not in private/incognito mode
- Try exporting data to verify storage works
Quotes not appearing?
- Open browser console (F12) to check for errors
- Verify quotes.js loads correctly
- Check localStorage isn't full
Streaks not calculating?
- Completion history must have dates in YYYY-MM-DD format
- Check browser's date timezone settings
- Export data to inspect completionHistory structure
Layout issues on Safari?
- Webkit flexbox prefixes are included for compatibility
- Try clearing browser cache and reloading
- Update Safari to the latest version
Open source, free to use and modify.
Built for productivity and personal growth.
Remember: Consistency compounds. One day at a time.