- TypeScript 96.5%
- JavaScript 1.8%
- Dockerfile 1%
- CSS 0.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| apps/web | ||
| docs | ||
| packages/core | ||
| scripts | ||
| .dockerignore | ||
| .gitignore | ||
| .npmrc | ||
| docker-compose.yml | ||
| Dockerfile | ||
| LICENSE | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| tsconfig.base.json | ||
HabitTracker
Beautiful, local-first habit tracker. Web-first (Next.js), shared domain core for future Expo iOS/Android.
See docs/DESIGN.md for the full product and architecture plan.
Stack
- apps/web — Next.js 15 App Router, Tailwind CSS 4, Dexie (IndexedDB)
- packages/core — pure TypeScript domain (schedules, streaks, progress, stats)
Setup (dev)
pnpm install
pnpm dev
pnpm dev waits until the server is accepting connections, then opens the browser.
Next.js prints the Local URL before it is ready — if you open that link too early you get a connection error that goes away on refresh. Use BROWSER=none pnpm dev to skip auto-open, or pnpm dev:raw for plain next dev.
Docker (local server)
Production image serves the Next.js app on port 3000 inside the container.
# Build, wait until healthy, open browser (host port 3080)
pnpm docker:up
# Or manually:
docker compose up -d --build
# Wait for "Ready" in logs before opening the URL
docker compose logs -f
# Stop
docker compose down
Open http://localhost:3080 only after the container is up — the port is published as soon as Docker starts the container, a moment before Node is listening.
Without Compose:
docker build -t habit-tracker .
docker run --rm -p 3080:3000 habit-tracker
Note: Habit data is stored in the browser (IndexedDB), not in the container. Back up via Settings → Backup & sync → Export JSON if you clear site data.
Forgejo Actions (TrueNAS)
- CI (
.forgejo/workflows/ci.yml) —runs-on: docker(node:lts): test, typecheck, build. - Deploy (
.forgejo/workflows/deploy.yml) —runs-on: docker-clion push tomainor manual dispatch:docker compose upon the NAS host Docker engine.
Runner must expose host Docker to job containers (DooD):
| Setting | Value |
|---|---|
| Label | docker-cli:docker://docker:27-cli |
| Volume | /var/run/docker.sock → runner |
container.options |
-v /var/run/docker.sock:/var/run/docker.sock |
| Variable (optional) | HOST_INTERNAL_URL — Forgejo URL reachable from job containers |
App stack is owned by Actions/compose (name: habit-tracker, host port 3080). Do not also manage the same container as a separate TrueNAS Custom App.
Scripts
| Command | Description |
|---|---|
pnpm dev |
Start web app; open browser when ready |
pnpm dev:raw |
Start web app without wait/open helper |
pnpm test |
Run all package tests |
pnpm typecheck |
TypeScript check |
pnpm build |
Production build |
pnpm docker:up |
Build, run container, wait, open browser |
docker compose up -d --build |
Build & run production container |
Features (MVP)
- Today dashboard with overall % ring and per-habit progress rings
- Add habit from templates or custom
- Edit habit (goals, frequency, circle click action, start date, lists)
- History: Trends chart, per-habit bars, Archive
- Settings: theme, streaks, vacation mode, start of week/day, export/import
- Fully offline — data stays in the browser
License
Private / unlicensed.