An offline-first PWA habit tracker — personalised by age group and sex, grounded in habit formation science. No account, no backend, no tracking.
Live app: https://habitio.rafal-sladek.com/
Improve your life with science-backed habits — personalised, private, and offline-first. No account needed.
Onboarding → Consent → Today → Add Habit → Journal → Journal Summary → Stats → Settings
- Personalised suggestions — habits ranked by age group (teen / young adult / adult / midlife / senior) and sex, based on demographic research
- Formation arc — each habit shows its phase (🌱 Learning → 🔨 Building → ⚡ Forming → ✨ Formed) across a science-backed 66-day journey
- Morning routine — tag habits as morning to group and prioritise them
- Journal — daily prompts: gratitude, affirmations, wins, reflection
- Stats — streaks, weekly progress, 28-day heatmap, 30-day performance per habit
- Offline-first PWA — installs on home screen, works without internet
- Optional AI coach — on-demand encouraging but candid feedback via Cloudflare Worker + Workers AI, with compact summaries and daily budget caps
- Export / Import — JSON backup for cross-device migration
- Multilingual — 20 languages: English, Deutsch, Polski, Português, Français, Русский, हिन्दी, Українська, عربي مصري, Shqip, Srpski, Bayrisch, Español, Italiano, Română, Nederlands, Türkçe, Ελληνικά, Hrvatski, Català
- Prefer not to say — sex option in onboarding and settings for inclusive personalisation
Files are split for clarity; no build step required.
| File | Purpose |
|---|---|
index.html |
App shell and markup |
styles.css |
All styles |
i18n.js |
All translations (20 languages) + t(), DN(), MN() helpers |
app.js |
All application logic |
suggestions.js |
Habit suggestion data with demographic scoring |
sw.js |
Service worker — network-first app shell + offline cache fallback (cache: habitio_v9) |
manifest.json |
PWA manifest |
icons/ |
Favicon, app icons (16, 32, 192, 512px + SVG), hero WebP/PNG |
worker/ |
Cloudflare Worker for feedback issues + optional AI coach |
All 68 suggested habits organized by category with descriptions and recommended cadence:
→ View full habits list — Health & Body · Mind & Focus · Digital Detox · Relationships · Productivity · Micro Learning
Core tracking data is stored client-side using the browser's localStorage API.
- Storage key:
habitio_v9, format: JSON - Habits, checks, journal, and settings stay local to the device/browser
- The app works fully offline for tracking, journaling, stats, import, and export
- Habit IDs use
crypto.randomUUID()for collision-free tracking - Data is local to the device/browser; clearing browser storage deletes all data
The AI coach is opt-in and on-demand:
- No habit data is sent anywhere until the user presses the AI Coach button
- The browser sends a compact progress summary, not raw
localStorage - Journal text is excluded by default and only sent if the user explicitly enables it
- The Cloudflare Worker enforces daily request and token-style budget caps before calling Workers AI
- AI responses are stored only in the user's local browser state unless they export a backup
Backup & restore: Export button downloads a JSON file. Import on any device to restore or migrate.
GitHub Actions runs Playwright e2e tests on Desktop, Mobile (Pixel 5), and Tablet (768×1024) viewports against a local dev server before deploying to GitHub Pages. Deployment is blocked if any test fails. Lighthouse CI runs after each deploy.
push to main → Playwright tests (desktop + mobile + tablet) → deploy to Pages → Lighthouse CI
When you add or modify tests, regenerate the badges with:
node scripts/generate-badges.jsThis will update:
- Overall test count badge
- Device-specific badges (Desktop, Mobile, Tablet, iPhone)
- Individual test category badges
Commit the generated badge files in badges/ with your test changes.
Lighthouse CI scores (avg of 6 runs — 3 mobile + 3 desktop — per deploy):
| Measured at (UTC) | Version | Commit | Perf | A11y | Best Practices | SEO |
|---|---|---|---|---|---|---|
| 2026-04-01 23:07 | v2.9 | fix(worker): allow all origin… | 89 | 90 | 82 | 100 |
| 2026-04-01 22:58 | v2.9 | feat(ui): v2.9 suggestions | 90 | 90 | 82 | 100 |
| 2026-04-01 21:38 | v2.7 | fix(ci): wrangler semver | 87 | 90 | 82 | 100 |
Run
node scripts/update-pagespeed.jsto pull the latest CI run and prepend a new row.
Key optimisations applied:
- Non-blocking Google Fonts (preconnect + preload swap)
- Hero image served as WebP (290 KB → 16 KB, 94% smaller) with PNG fallback
fetchpriority="high"on LCP image- WCAG AA contrast on all text elements
viewport-fit=coverwith safe-area insets for device nav bars
Personalisation logic and habit formation features are grounded in published research.
- Median formation time is 59–66 days, not 21 — Lally et al., 2010, EJSP
- Missing a day does not break formation — same Lally study
- Morning routines show 43% higher success rates — habit timing research
- Self-selected habits have 37% higher success than externally imposed — habit autonomy research
- Brain handoff: prefrontal cortex → basal ganglia as habits automate — WJARR
- Physical activity: 80% of adolescents don't meet WHO guidelines; inactivity worsens after 60
- Diet: women consistently lead; men 18–29 have the worst diets
- Sleep & screens: 45% of US teens say social media hurts sleep; girls more affected — Pew Research
- Substances: males higher prevalence across all categories; rates drop after 60 — PubMed Central
- Mental health: women more proactive (therapy, mindfulness); men 30+ show lower distress — ScienceDirect
- Reading gap: 23% of Americans haven't read a book in a year; men less likely than women
First-time setup installs Node.js dependencies and Playwright test browsers.
Option A — Windows 11 (PowerShell):
powershell -ExecutionPolicy Bypass -File scripts/setup.ps1Option B — macOS / Linux (Bash):
bash scripts/setup.shManual setup (all platforms):
yarn install # Install Node.js dependencies
npx playwright install # Install Playwright browsers (Chromium, Firefox, WebKit)No build step needed — serve the files with any static server.
Option A — Node (recommended):
npx serve .
# Open http://localhost:3000Option B — Python:
python -m http.server 8080
# Open http://localhost:8080Option C — VS Code:
Install the Live Server extension, right-click index.html → Open with Live Server.
The app uses a Service Worker for offline caching. The SW only activates over HTTP (not
file://), so always use a local server rather than openingindex.htmldirectly.
# Install dependencies and Playwright browsers
yarn install
npx playwright install chromium
# Run tests (desktop + mobile + tablet)
yarn test
# Format code
yarn formatDeploy by pushing to main — GitHub Actions tests then deploys automatically.
The Worker now has two responsibilities:
POST /orPOST /feedbackcreates a GitHub issue from in-app feedbackPOST /coachgenerates AI coach feedback through Workers AI
Required configuration in worker/wrangler.toml:
GITHUB_TOKENsecret for feedback issue creation[ai] binding = "AI"for Workers AI- optional
COACH_BUDGETSKV namespace for durable daily budget tracking - optional coach vars like
COACH_MAX_DAILY_REQUESTSandCOACH_MAX_OUTPUT_TOKENS
| Script | Purpose | Requirements |
|---|---|---|
node scripts/take-screenshots.js |
Regenerate all docs/ screenshots (mobile, desktop, tablet) |
Local server on :3000 + Playwright |
node scripts/generate-gif.js |
Create docs/user-journey.gif from mobile screenshots |
ffmpeg + screenshots already in docs/ |
node scripts/generate-badges.js |
Update badges/tests.json with active test count |
— |
When UI changes (layout, colours, new screens, copy), regenerate all screenshots and the GIF:
# 1. Start the local server
npx serve . -p 3000
# 2. Regenerate all screenshots (mobile 393×852, desktop 1280×800, tablet 820×1180)
node scripts/take-screenshots.js
# 3. Regenerate the animated user-journey GIF from mobile screenshots
node scripts/generate-gif.js
# 4. Convert images to WebP (if updating hero image)
ffmpeg -i icons/hero-onboarding.png -c:v libwebp -quality 82 icons/hero-onboarding.webpThe GIF uses 8 mobile screenshots in user-journey order (2 s per frame, 393 px wide, palette-optimised).
Individual screenshots remain in docs/ for desktop/tablet previews and PR reviews.
