Habits is a premium, local-first habit tracking web application built on React, Vite, and Cloud Firestore. Inspired by James Clear's Atomic Habits, the application places identity at the center of behavior change, helping users vote for their desired self through daily routines and audits.
The interface features a warm, high-contrast, premium color scheme (terracotta, peach, and sage green) with smooth transitions, responsive layouts, and interactive guides.
- Identity Definition: Users define who they want to become (e.g., "The Athlete", "The Writer") rather than just what they want to achieve.
- Routines Stack: Couples new habits directly with existing anchor triggers using implementation intentions ("After I [Anchor], I will [Habit]").
- Daily Check-Ins: Clear, responsive checkboxes to track habits completed today.
- 2-Minute Rule Version: Allows users to log scaled-down versions of habits to maintain consistency ("Do 5 squats" instead of "Full workout").
- Anti-Habits Slip Logging: Track triggers and note environment friction adjustments when slips occur.
- Leveling & Progress: Earn progress votes for every completion, leveling up from Seedling to Atomic and Identity Locked.
- Engines (Good Habits Cues): Design space preparation strategies to make cues obvious (e.g., unrolling your exercise mat next to the bed).
- Brakes (Anti-Habits Friction): Establish commitment devices to make bad habits difficult or invisible (e.g., storing chargers outside the bedroom).
- AI Coach Suggestions: Opt-in Gemini API integration using Gemma 4 to suggest custom routines and environment prep cues, with robust client-side offline heuristic fallbacks.
- 14-Day Completion curves: Area charts showing daily good habit compliance percentage.
- Anti-Habit Sobriety Streaks: Line charts graphing days free since last logged slips.
- Evidence Logs: Summarized cards listing identity strength calculated from completions vs slips.
- Reflections History: Chronological log of past weekly review reflections with smooth scroll anchor focus.
- Auditing prompt to log Wins, Challenges, Lessons Learned, and Next Week's Focus.
- Displays calendar date ranges dynamically alongside ISO week numbers.
- Employs a 2.5-second Firestore connection timeout safety guard to prevent hanging loading screens.
- Displays a user-friendly, blocking "Connection Unreachable" screen when Firestore is unreachable or offline, allowing users to retry their connection.
- Integrates toast notifications warning the user if the network connection is slow or degraded.
- Client-Side Selector (
useMemo): Intercepts loaded context states to filter and deduplicate records before they are rendered, resolving UI bloat instantly. - Background Database Cleanup: Optimizes and purges duplicate Firestore documents concurrently using
Promise.alldeletions and updates, keeping database sizes small.
- SDK & Endpoint Routing: Built using
@google/genai. Gemma models (specificallygemma-4-26b-a4b-it) require initializing the client withapiVersion: "v1beta"to route calls correctly. - Model Constraints: Removes
thinkingConfigparameters from content generation calls as Gemma does not support them and returns HTTP 400. - Production CORS Restriction: Direct browser-to-API calls are blocked by the Gemini API in production (on origins like
*.vercel.app) to prevent key exposure. The application gracefully falls back to local offline heuristics, and production deployments should route API calls through a secure backend proxy serverless function.
- Vitest Test Suite: Includes 45 unit and integration tests covering context providers, state sync loops, routing guards, and UI wizard flows.
- GitHub Actions CI: Automated workflow runs linting, unit tests, and production build checks on every push and pull request to
main.
- Node.js (v18+)
- Firebase Project with Firestore and Authentication enabled (Google & Email/Password providers).
Create a .env file in the project root (use .env.example as a template):
VITE_FIREBASE_API_KEY=your_api_key_here
VITE_FIREBASE_AUTH_DOMAIN=your_auth_domain_here
VITE_FIREBASE_PROJECT_ID=your_project_id_here
VITE_FIREBASE_STORAGE_BUCKET=your_storage_bucket_here
VITE_FIREBASE_MESSAGING_SENDER_ID=your_messaging_sender_id_here
VITE_FIREBASE_APP_ID=your_app_id_here
# AI Coach Configuration
VITE_GEMINI_API_KEY=your_gemini_api_key_here
VITE_GEMINI_MODEL=gemma-4-26b-a4b-itnpm installnpm run devThe application will run locally at http://localhost:5173.
npm run buildCreates minified, production-ready assets inside the dist/ directory.
npm run lintChecks the codebase for any syntax errors or style issues using ESLint.
npm testRuns the unit test suite using Vitest.
userId(String)level(Number)totalVotes(Number)createdAt/updatedAt(ISO Strings)
name(String)beliefStatement(String)createdAt(ISO String)
identityId(String)identityName(String)title(String)description(String)category(String)time(String)location(String)stackedHabit(String)twoMinRule(String)environmentPrep(String)immediateReward(String)
habitId(String)identityId(String)identityName(String)dateNormalized(String,YYYY-MM-DD)isTwoMinVersion(Boolean)notes(String)completedAt(ISO String)
year(Number)weekNumber(Number)satisfaction(Number)reflection(Map:wins,challenges,learning,nextWeek)status(String:'draft'|'completed')