Your consistency, beautifully tracked.
A gamified habit & streak tracker with a real-time 3D "Streak Orb" that grows as you build consistency β built with Next.js 14, Supabase, and Three.js.
Cadence turns habit-building into something you actually want to look at. Instead of a boring checklist, every habit you track feeds into a living 3D orb that visually strengthens β from a dormant wireframe sphere to a pulsing, particle-wrapped centerpiece β as your streaks grow.
It's a full-stack, production-shaped reference app: real auth, row-level security, optimistic UI, timezone-correct streak math, unit + E2E tests, and a guest demo mode β built as a portfolio-grade example of a polished Next.js + Supabase product, not a toy CRUD app.
π§ͺ Want to poke around without signing up? Hit "Try Interactive Guest Demo" on the login page β no account needed.
| Landing Page | Settings (Dark Mode) |
|---|---|
![]() |
![]() |
| Dashboard & Streak Orb | Habit Detail & Heatmap |
![]() |
![]() |
- 3D Streak Orb β a
react-three-fiberscene that reacts to your overall consistency across 4 strength levels (dormant β building β established β strong), with instanced particle auras and orbit rings at higher levels. Automatically falls back to a static, accessible SVG on low-end devices, when WebGL is unavailable, or whenprefers-reduced-motionis set. - Timezone-correct streak logic β all streak math runs on local calendar dates (never raw UTC timestamps), mirrored client-side (for instant optimistic UI) and server-side (Postgres
get_current_streak()function) so they never drift apart. - Milestone celebrations β hitting 7 / 30 / 100 / 365-day streaks fires a full-screen confetti celebration, tracked via a unique DB constraint so it only ever fires once per milestone per habit.
- Focus Mode β an optional countdown timer per habit with a Web Audio chime on completion β no external audio assets needed.
- Consistency heatmap β a 26-week GitHub-style contribution calendar per habit.
- Guest demo account β one-click, no-signup exploration, reset nightly via a scheduled Supabase Edge Function.
- Weekly email recaps β opt-in summary emails (via Resend) of completions, focus time, and active habits.
- Full accessibility pass β screen-reader-only status summaries on every visual widget (orb, heatmap), keyboard-navigable dialogs/menus (Radix primitives), WCAG AA-checked color palette, and device-capability guard-railing (
lib/device.ts) before any WebGL is ever mounted. - Dark mode and a cohesive, animated design language (see Design & Credits).
| Layer | Choice |
|---|---|
| Framework | Next.js 14 (App Router, Server Components) |
| Language | TypeScript (strict mode) |
| Database / Auth | Supabase (Postgres, Row-Level Security, Auth) |
| Data fetching / cache | TanStack Query |
| Client state | Zustand |
| 3D rendering | Three.js + react-three-fiber + drei |
| Styling | Tailwind CSS + shadcn/ui + Radix UI |
| Animation | GSAP + React Bits (animated backgrounds, text, and card effects) |
| Resend | |
| Testing | Vitest (unit) + Playwright (E2E) |
| Deployment | Vercel (app) + GitHub Actions (scheduled jobs) |
cadence/
βββ app/
β βββ (marketing)/ # Public landing page β zero client-side data deps, fast LCP
β βββ (app)/ # Authenticated app shell β dashboard, habit detail, settings
β βββ login/ # Auth screen (email/password, magic link, guest demo)
β βββ auth/callback/ # Supabase OAuth/magic-link callback handler
β βββ api/cron/ # Vercel-invoked cron routes (weekly summary, demo reset)
βββ components/
β βββ features/ # Domain components (habit-card, streak-orb, focus-timer, ...)
β βββ ui/ # shadcn/Radix-based primitives
β βββ react-bits/ # Vendored, theme-matched React Bits components
βββ hooks/ # TanStack Query hooks (useHabits, useCheckIn, useStreakStats, ...)
βββ lib/
β βββ streaks.ts # Pure, unit-tested streak calculation functions
β βββ device.ts # WebGL / reduced-motion / low-end-device guard-railing
β βββ palette.ts # Constrained, WCAG-AA-checked icon & color tokens
β βββ supabase/ # Browser, server, middleware, and admin Supabase clients
βββ store/ # Zustand UI store (modals, celebration queue, 3D toggle)
βββ supabase/
β βββ migrations/ # SQL schema + RLS policies + streak function
β βββ functions/ # Deno Edge Functions (weekly-summary, reset-demo-data)
βββ tests/
β βββ unit/ # Vitest
β βββ e2e/ # Playwright
βββ .github/workflows/ # CI + Supabase keep-alive cron
git clone https://github.com/x0911/cadence.git
cd cadence
npm installcp .env.example .env.localFill in .env.local:
| Variable | Where to find it |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Supabase Dashboard β Project Settings β API |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY |
Supabase Dashboard β Project Settings β API keys (publishable key) |
SUPABASE_SECRET_KEY |
Supabase Dashboard β Project Settings β API keys (secret key) β server-only, never expose to the client |
SUPABASE_JWKS_URL |
https://<project-ref>.supabase.co/auth/v1/.well-known/jwks.json |
RESEND_API_KEY |
resend.com dashboard (optional β weekly emails no-op without it) |
CRON_SECRET |
Any random string β protects the /api/cron/* routes from unauthenticated calls |
Run the schema migration against your Supabase project:
# via Supabase CLI
supabase link --project-ref <your-project-ref>
supabase db pushThis creates all tables, RLS policies, the get_current_streak() function, and the auto-profile-creation trigger β see supabase/migrations/001_initial_schema.sql.
npm run devVisit http://localhost:3000.
npm run test # Vitest unit tests
npm run test:e2e # Playwright E2E (requires a running build)
npm run typecheck # TypeScript strict check
npm run lint # ESLintSupabase free-tier projects pause after ~7 days without database activity. This repo includes .github/workflows/supabase-keepalive.yml, which pings the Supabase REST API every 3 days via GitHub Actions β no server, no cost.
To enable it on your own fork:
- Go to your repo's Settings β Secrets and variables β Actions
- Add
SUPABASE_URLandSUPABASE_PUBLISHABLE_KEY(same values as your.env.local) - That's it β the workflow runs automatically, or trigger it manually from the Actions tab (
workflow_dispatch).
Cadence's visual language combines:
- A custom emerald-based design token system (
app/globals.css) shared between the UI chrome and the 3D Streak Orb's own color ramp, so the "orb colors" and "app colors" are always the same palette. - React Bits for animated backgrounds, kinetic text, and interactive card effects across the landing page and key in-app moments β themed to match the app's palette rather than used with default styling.
- shadcn/ui + Radix UI for accessible, unstyled-by-default primitives (dialogs, dropdowns, switches).
- Public API for third-party integrations (Zapier/Make)
- Mobile app (React Native) sharing the same Supabase backend
- Habit sharing / accountability partners
- Slack/Discord notifications for streak-at-risk reminders
- Optional Slack alert on GitHub Actions cron failure (currently relies on GitHub's default email notification)
Contributions and ideas are very welcome β see below.
This is an open-source, portfolio project and contributions are genuinely welcome:
- Fork the repo and create a feature branch
- Follow the existing code style (
npm run lint:fixandnpm run formatbefore committing) - Add/update tests for any logic change (
lib/,hooks/) - Open a PR describing the change and why
Good first areas to contribute: additional React Bits component integrations, more Playwright E2E coverage, i18n, or accessibility audits.
MIT Β© Hamdi Mohamed β free to use, modify, and build on.
Built by Hamdi Mohamed, Senior Frontend Engineer (Vue/Nuxt background, also comfortable in React, WordPress/PHP, and Python) β this project was built to demonstrate full-stack product thinking in the React/Next.js ecosystem: real auth and RLS, correct timezone-aware business logic, accessibility guard-railing around a custom WebGL feature, automated testing, and a deliberate, documented design system rather than an out-of-the-box template.
π« Feel free to reach out via GitHub issues or connect on LinkedIn for feedback or collaboration.



