{"id":48782021,"url":"https://github.com/domhhv/habitrack","last_synced_at":"2026-04-13T14:44:21.217Z","repository":{"id":215795727,"uuid":"739552573","full_name":"domhhv/habitrack","owner":"domhhv","description":"A simple calendar app for tracking habits, built with React and Supabase","archived":false,"fork":false,"pushed_at":"2026-04-06T21:57:39.000Z","size":6734,"stargazers_count":8,"open_issues_count":4,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-13T14:44:18.189Z","etag":null,"topics":["calendar","framer-motion","habits","heroui","phosphor-icons","react","react-aria","sql","sqlfluff","supabase","supabase-auth","supabase-storage","tailwind","testing-library-react","typescript","vercel","vite","vitest","yarn","zustand"],"latest_commit_sha":null,"homepage":"https://www.habitrack.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/domhhv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"docs/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-01-05T21:06:55.000Z","updated_at":"2026-04-01T20:02:36.000Z","dependencies_parsed_at":"2026-03-25T00:03:54.619Z","dependency_job_id":null,"html_url":"https://github.com/domhhv/habitrack","commit_stats":null,"previous_names":["domhhv/react-habits-calendar-tracker","domhhv/habitrack"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/domhhv/habitrack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domhhv%2Fhabitrack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domhhv%2Fhabitrack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domhhv%2Fhabitrack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domhhv%2Fhabitrack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/domhhv","download_url":"https://codeload.github.com/domhhv/habitrack/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domhhv%2Fhabitrack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31757482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T13:27:56.013Z","status":"ssl_error","status_checked_at":"2026-04-13T13:21:23.512Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","framer-motion","habits","heroui","phosphor-icons","react","react-aria","sql","sqlfluff","supabase","supabase-auth","supabase-storage","tailwind","testing-library-react","typescript","vercel","vite","vitest","yarn","zustand"],"created_at":"2026-04-13T14:44:20.322Z","updated_at":"2026-04-13T14:44:21.211Z","avatar_url":"https://github.com/domhhv.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eHabitrack\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n\u003ca href=\"https://react.dev/\" target=\"_blank\" title=\"React\"\u003e\u003cimg src=\"https://i.ibb.co/dwS2knBp/atom.png\" alt=\"React\" width=\"32\" height=\"32\" /\u003e\u003c/a\u003e\n\u0026nbsp;\n\u003ca href=\"https://www.typescriptlang.org/\" target=\"_blank\" title=\"TypeScript\"\u003e\u003cimg src=\"https://i.ibb.co/Kq8DY4f/typescript.png\" alt=\"TypeScript\" width=\"32\" height=\"32\"\u003e\u003c/a\u003e\n\u0026nbsp;\n\u003ca href=\"https://vite.dev/\" target=\"_blank\" title=\"Vite\"\u003e\u003cimg src=\"https://i.ibb.co/FWtjy8J/Vite-js.png\" alt=\"Vite\" width=\"32\" height=\"32\"\u003e\u003c/a\u003e\n\u0026nbsp;\n\u003ca href=\"https://tailwindcss.com/\" target=\"_blank\" title=\"TailwindCSS\"\u003e\u003cimg src=\"https://i.ibb.co/mR0BWJx/Tailwind-CSS.png\" alt=\"Tailwind\" width=\"32\" height=\"32\" /\u003e\u003c/a\u003e\n\u0026nbsp;\n\u003ca href=\"https://www.heroui.com/\" target=\"_blank\" title=\"HeroUI\"\u003e\u003cimg src=\"https://i.ibb.co/j0K0TCw/heroui-logo.png\" alt=\"HeroUI\" width=\"32\" height=\"32\"\u003e\u003c/a\u003e\n\u0026nbsp;\n\u003ca href=\"https://supabase.com/\" target=\"_blank\" title=\"Supabase\"\u003e\u003cimg src=\"https://i.ibb.co/s9hK6ZSn/supabase-logo-icon.png\" alt=\"Supabase\" width=\"32\" height=\"32\"\u003e\u003c/a\u003e\n\u0026nbsp;\n\u003ca href=\"https://reactrouter.com/\" target=\"_blank\" title=\"React Router\"\u003e\u003cimg src=\"https://i.ibb.co/zTzh8rCd/react-router-logo-light.png\" alt=\"React Router\" width=\"32\" height=\"32\"\u003e\u003c/a\u003e\n\u0026nbsp;\n\u003ca href=\"https://vitest.dev/\" target=\"_blank\" title=\"Vitest\"\u003e\u003cimg src=\"https://i.ibb.co/99zTCxvx/vitest.png\" alt=\"Vitest\" width=\"32\" height=\"32\"\u003e\u003c/a\u003e\n\u0026nbsp;\n\u003ca href=\"https://testing-library.com/\" target=\"_blank\" title=\"React Testing Library\"\u003e\u003cimg src=\"https://i.ibb.co/YLnX0VY/octopus-64x64.png\" alt=\"React Testing Library\" width=\"32\" height=\"32\"\u003e\u003c/a\u003e\n\n\u003cdiv style=\"display: flex; justify-content: center; gap: 8px;\"\u003e\n\n[![RelativeCI](https://badges.relative-ci.com/badges/ZMp2Jc2sGq2jCm6ArH0A?branch=main\u0026style=flat)](https://app.relative-ci.com/projects/ZMp2Jc2sGq2jCm6ArH0A)\n\n![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/domhhv/habitrack?utm_source=oss\u0026utm_medium=github\u0026utm_campaign=domhhv%2Fhabitrack\u0026labelColor=171717\u0026color=FF570A\u0026link=https%3A%2F%2Fcoderabbit.ai\u0026label=CodeRabbit+Reviews)\n\n\u003c/div\u003e\n\n\u003c/div\u003e\n\nHabitrack is a simple and intuitive web app designed for logging habits and v isualizing them on a calendar view.\n\nThis app showcases the use of the following tools and technologies:\n\n- React 19 with TypeScript 5.9, bundled with [Vite 7](https://vite.dev/)\n- [React Router](https://reactrouter.com) v7 for routing (declarative mode)\n- [Zustand](https://zustand.docs.pmnd.rs/) v5 for global state management\n- [Tailwind CSS](https://tailwindcss.com) v4 for styling\n- [HeroUI](https://www.heroui.com/) for the UI components\n- React Aria [calendar hooks](https://react-spectrum.adobe.com/react-aria/useCalendar.html) to generate the calendar view\n- [Supabase](https://supabase.io) for Authentication, Database and Storage\n- [Vitest](https://vitest.dev/) and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) for unit-testing\n- ESLint, Prettier, Husky, and SQLFluff for linting and formatting\n- Docker for running a local Supabase instance\n- GitHub Actions for CI/CD and Vercel for deployment\n\n## Features\n\n- **Customizable Habits**: Add, remove, and customize habits to fit your routine. Associate your habits with traits and icons.\n- **Calendar View**: Visualize your habits on a monthly calendar.\n- **Daily Tracking**: Easily add daily entries of your habits.\n- **User Authentication**: Sign up and log in to your account to retain your habits and entries.'\n- **Responsive Design**: Enjoy a seamless experience on any device.\n- **PWA**: Install the app on your device for quick access.\n\n## Roadmap\n\n- [x] **Dark Mode**: Switch between light and dark themes.\n- [x] **Weekly View**: View your habits on a weekly calendar.\n- [x] **Daily View**: Dive into your habits on a daily calendar.\n- [ ] **Export**: Export your habits and entries.\n- [ ] **Categories**: Group habits into categories.\n- [ ] **Environments**: Associate habits with environments where they occur.\n- [x] **Habit Stocks**: Maintain a stock count for habits that require consumable resources.\n- [x] **Habit Spending**: Track spending related to habits.\n- [ ] **Habit Presets**: Use predefined habit templates for quick setup.\n- [ ] **Log Presets**: Create and use log entry presets for faster logging.\n- [ ] **Statistics**: Track your progress with insightful statistics.\n- [ ] **Enriched Habit Streaks**: Extended options to visualize and track habit streaks (basic one-off streaks are displayed under /habits).\n- [ ] **Sharing**: Share your calendar with trusted people.\n- [ ] **Group Calendars**: Form or break habits together with friends or under a supervision of a coach.\n- [ ] **Group Challenges**: Participate in habit challenges within groups.\n- [ ] **Notifications**: Get reminders to log your habits via PWA notifications and later via email.\n- [ ] **Offline Support**: Use the app without an internet connection.\n\nThere's also a public roadmap on Featurebase where you can upvote and suggest new features: [Habitrack Public Roadmap](https://habitrack.featurebase.app/roadmap).\n\n### Tech Debt\n\n- [x] **Migrate to Vitest**: Replace Jest with Vitest.\n- [x] **Migrate to ESLint v9**: Update to ESLint v9 and use flat config.\n- [ ] **Migrate to HeroUI 3**: Update to [HeroUI v3](https://v3.heroui.com/) (currently in beta) once it reaches stable release.\n\n## Local development\n\n### Prerequisites\n\n- [Git](https://git-scm.com/)\n- [Node.js](https://nodejs.org/en/) (22.22.2)\n- [Docker](https://docs.docker.com/get-started/get-docker/)\n- Yarn is used as a package manager and is automatically available via Corepack (bundled with Node.js)\n\n### Initial Setup\n\nFollow these steps to get the project up and running on your local machine.\n\n1. **Clone the repository:**\n\n   ```bash\n   git clone https://github.com/domhhv/habitrack.git\n   ```\n\n2. **Navigate to the project directory:**\n\n   ```bash\n   cd habitrack\n   ```\n\n3. **Install dependencies:**\n\n   ```bash\n   yarn install\n   ```\n\n### Local Database Setup\n\nThe project uses Supabase for database operations.\n\nThe Supabase project configuration, seeds, and migrations live under the `supabase` directory.\n\nTo set up a local Supabase instance, run the following commands (Docker required).\n\n1. **Start the local Supabase instance:**\n\n   ```bash\n   yarn db:start\n   ```\n\n   This command starts Supabase Docker containers based on `supabase/config.toml` and creates a local Postgres database and services.\n\n   It should output the Studio URL, Database URL, and Project URL, among other info. Use the Studio URL to access the local Supabase dashboard in the browser, and the Database URL to connect to the local database directly if needed.\n\n2. **Retrieve API URL and anon key:**\n\n   Run the following command to retrieve the API URL and anon key for the local Supabase instance:\n\n   ```bash\n   yarn db:status -o env\n   ```\n\n   This command outputs the environment variables needed to connect to the local Supabase instance, including `API_URL` and `ANON_KEY`.\n\n3. **Environment variables**\n\n   Create a `.env.development` file in the root directory of the project and add the following environment variables:\n\n   ```env\n   SUPABASE_URL=\u003cAPI URL\u003e\n   SUPABASE_ANON_KEY=\u003cANON_KEY\u003e\n   ```\n\n4. **Apply migrations and seed the database:**\n\n   ```bash\n   yarn db:reset\n   ```\n\n   This command resets the local database to a clean state, applies migrations from `supabase/migrations`, and seeds the db with essential initial data based on `supabase/seed.sql`.\n\n### Run the app\n\nOnce the dependencies are installed and the local Supabase instance is running, you can run the app locally:\n\n```bash\nyarn dev\n```\n\nThis command starts the development server and opens the app in your default browser.\n\n### Database Migrations\n\nThere are a few ways to create and run migrations in the project.\n\n- **[Recommended] Change or create [declarative database schema](https://supabase.com/docs/guides/local-development/declarative-database-schemas) SQL files under `supabase/schemas` directory as needed**\n\nThis project uses declarative database schema management, so the preferred way to make changes to the database schema is to modify the SQL files under `supabase/schemas` directory.\n\nIf you need to modify an existing table, add a new table/type/function, or make any other schema changes, do so by editing or adding SQL files in the `supabase/schemas` directory, then run:\n\n```bash\nyarn db:diff -f \u003cyour-migration-name\u003e\n```\n\n- **Diffing the Supabase Studio database schema changes to automatically generate a new migration file**\n\nDo the necessary changes in the local Supabase studio and then run the following to automatically generate a new migration file:\n\n```bash\nyarn db:diff -f \u003cyour-migration-name\u003e\n```\n\n- **Creating a new migration file manually**\n\nTo create a new migration file manually, run the following command:\n\n```bash\nyarn db:migration:new \u003cyour-migration-name\u003e\n```\n\n---\n\nEither way, the new migration file will be created in the `supabase/migrations` directory. Write/change the SQL queries in the migration file to reflect the changes you want to make to the database schema. Then, apply the migration by running:\n\n```bash\nyarn db:migration:up # or\nyarn db:reset # to reset the local DB and apply all migrations\n```\n\nAfter applying the migration, you also need to regenerate Supabase types by running:\n\n```bash\nyarn db:gen-types\n```\n\nOnce the migration ends up in the `main` branch, it will be automatically applied to the production database.\n\n\u003e Important step: After applying any new migrations, always remember to regenerate Supabase types by running `yarn db:gen-types` to keep the types in sync with the database schema.\n\n### Testing\n\nThe project uses [Vitest](https://vitest.dev/) as the test runner and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) for unit testing of React components.\n\nTo run the tests, use the following command:\n\n```bash\nyarn test\n```\n\nOther test-related commands include:\n\n```bash\nyarn test:coverage # Run all tests and generate coverage report\nyarn test:watch # Run all tests in watch mode\nyarn test:no-cache # Run all tests without cache\n```\n\n### Linting\n\nThere are two types of linting in the project: JavaScript/TypeScript linting and SQL linting.\n\n#### JS/TS\n\nThe project uses [ESLint](https://eslint.org/) v9 with a custom flat config for linting. To run ESLint, use the following command:\n\n```bash\nyarn eslint:check # Check for linting errors\nyarn eslint:fix # Fix linting errors\n```\n\n#### SQL\n\nIn addition to ESLint, the project uses [SQLFluff](https://docs.sqlfluff.com/en/stable/) for linting SQL queries under `supabase` directory. To run SQLFluff (Docker required), use the following command:\n\n```bash\nyarn lint:sql # Lint SQL queries\nyarn fix:sql # Find fixable linting violations in SQL queries and apply fixes\n```\n\n### Formatting\n\nThe project uses [Prettier](https://prettier.io/) for formatting. To run Prettier, use the following command:\n\n```bash\nyarn prettier:check # Check for formatting errors\nyarn prettier:write # Fix formatting errors\n```\n\n### Building\n\nTo create a local production-like build of the app, run the following command:\n\n```bash\nyarn build\n```\n\nYou can run the production build locally using the following command:\n\n```bash\nyarn preview\n```\n\n## CI/CD\n\nThe project uses GitHub Actions for CI/CD.\n\n### Pull Requests\n\nWhen you open a pull request, the following checks are run:\n\n- **Setup**: Install and cache Yarn dependencies.\n- **Typecheck**: Run TypeScript type checks.\n- **ESLint**: Run ESLint checks for JS/TS lint issues.\n- **SQLFluff**: Run SQLFluff checks for SQL lint issues.\n- **Prettier**: Run Prettier checks for formatting issues.\n- **Unit tests**: Run unit tests with Vitest (currently not required to pass as tests are incomplete).\n- **RelativeCI**: Visual regression tests powered by RelativeCI.\n- **Deploy preview**: Build and deploy the app to Vercel for preview.\n- **Coderabbit PR Review**: Automated code review powered by CodeRabbit.\n\nAll checks but the last one must pass before merging a pull request.\n\n### Merging to Main\n\nWhen a pull request is merged to the `main` branch, the following checks are run:\n\n- **Deploy app**: Build and deploy the app to Vercel.\n- **Migrate database**: Apply Supabase migrations to the production database, if any.\n\n## Contributing\n\nContributions are welcome! Feel free to open issues or pull requests for any improvements, bug fixes, or new features.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdomhhv%2Fhabitrack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdomhhv%2Fhabitrack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdomhhv%2Fhabitrack/lists"}