{"id":49141558,"url":"https://github.com/liviro/boob-o-clock","last_synced_at":"2026-04-24T02:04:30.278Z","repository":{"id":347896962,"uuid":"1195639957","full_name":"liviro/boob-o-clock","owner":"liviro","description":"Self-hosted dark-mode baby tracker for the infant nights","archived":false,"fork":false,"pushed_at":"2026-04-16T20:33:21.000Z","size":1149,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-16T21:19:09.342Z","etag":null,"topics":["baby-tracker","docker","golang","preact","pwa","self-hosted","sqlite"],"latest_commit_sha":null,"homepage":"","language":"Go","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/liviro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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},"funding":{"github":"liviro","ko_fi":"polinaturcu"}},"created_at":"2026-03-29T22:50:38.000Z","updated_at":"2026-04-16T20:33:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/liviro/boob-o-clock","commit_stats":null,"previous_names":["liviro/boob-o-clock"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/liviro/boob-o-clock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liviro%2Fboob-o-clock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liviro%2Fboob-o-clock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liviro%2Fboob-o-clock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liviro%2Fboob-o-clock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/liviro","download_url":"https://codeload.github.com/liviro/boob-o-clock/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liviro%2Fboob-o-clock/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32116514,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T00:31:26.853Z","status":"ssl_error","status_checked_at":"2026-04-22T00:30:22.894Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["baby-tracker","docker","golang","preact","pwa","self-hosted","sqlite"],"created_at":"2026-04-22T01:07:28.981Z","updated_at":"2026-04-22T01:07:32.278Z","avatar_url":"https://github.com/liviro.png","language":"Go","funding_links":["https://github.com/sponsors/liviro","https://ko-fi.com/polinaturcu"],"categories":[],"sub_categories":[],"readme":"# Boob O'Clock\n\nA nighttime baby sleep and feed tracker for breastfeeding parents. Built for one-handed use on a small phone screen.\n\nDark mode only. Single tap to record events. Long-press for time adjustments.\n\n## Why I built this\n\nI'm a new parent in the thick of newborn nights. At 3am, mid-feed, I genuinely could not remember which side and when I'd last fed on — and every baby tracker I found wanted an account, cloud sync, and a bright white screen in my face. So I vibecoded this for myself in a few evenings, and it's already been useful enough that I wanted to share it.\n\nJust your data, on your network, in the dark. If Boob O'Clock helped you survive the infant nights, you can [buy me a coffee](https://ko-fi.com/polinaturcu) — it means a lot.\n\n## What it tracks\n\nThe app models your night as a state machine. Depending on the current state, only the valid next actions are shown:\n\n- **Feeds** — start, switch breast (auto-flips), dislatch (awake or asleep). Tracks left/right duration separately.\n- **Sleep** — on me, in crib, in stroller. Tracks where the baby is sleeping.\n- **Transfers** — crib transfer attempts with deferred outcome (tap result when hands are free).\n- **Self-soothing** — baby put down awake or stirring in crib, settling without intervention.\n- **Resettling** — in-crib settling without a feed.\n- **Strolling** — the nuclear option when the crib isn't working.\n- **Diaper changes** — because shit happens, at any time.\n- **Ferber mode** — opt-in per night. Graduated check-in intervals (classic Ferber table), mood tracking (quiet / fussy / crying), and a countdown on the check-in button so you never check in too early. No-op when off; the rest of the app works exactly the same.\n\n## What it reports\n\n- Per-night summary: night duration, total sleep, total feed time, wake count, feed count, longest sleep block, individual sleep block durations, feed times\n- Ferber nights also show sessions, average time to settle, cry time, fuss time, check-ins, abandoned sessions, and quiet time\n- Color-coded timeline bar showing the night at a glance\n- Full event log with timestamps\n- Feed times scatter plot showing when feeds happen across nights\n- Real bedtime chart showing when the baby actually goes down\n- Trend charts with 3-night moving averages: longest sleep, total sleep, wake count, feed count, total feed time, feed time by breast (L/R)\n- Ferber trend charts (when any night had Ferber on): cry time per night, check-ins per night, avg time to settle\n- Ferber nights are highlighted as sage-green blocks on all non-Ferber trend charts, so you can correlate Ferber periods with broader sleep/feed changes\n- CSV export for backup or analysis\n\n## Screenshots\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/tracker-awake.png\" width=\"250\" alt=\"Tracker — awake state\"\u003e\n  \u003cimg src=\"docs/night-detail.png\" width=\"250\" alt=\"Night detail with timeline\"\u003e\n  \u003cimg src=\"docs/trends.png\" width=\"250\" alt=\"Trend charts with moving averages\"\u003e\n\u003c/p\u003e\n\n## Deploy\n\n### Docker Compose (recommended)\n\n```bash\ngit clone https://github.com/liviro/boob-o-clock.git\ncd boob-o-clock\ndocker compose up -d\n```\n\nThat's it. The app is at `http://localhost:8080`.\n\nTo update:\n\n```bash\ndocker compose build --no-cache\ndocker compose up -d\n```\n\nThe SQLite database lives in a named Docker volume (`boc-data`) and survives rebuilds. Back it up with:\n\n```bash\ndocker compose cp boob-o-clock:/data/boob-o-clock.db ./backup.db\n```\n\n### Docker (manual)\n\n```bash\ndocker build -t boob-o-clock .\ndocker run -d \\\n  --name boob-o-clock \\\n  --restart unless-stopped \\\n  -p 8080:8080 \\\n  -v boc-data:/data \\\n  boob-o-clock\n```\n\nTo change the port, set the `PORT` environment variable:\n\n```bash\ndocker run -d -e PORT=9090 -p 9090:9090 -v boc-data:/data boob-o-clock\n```\n\n### Binary\n\nRequires Go 1.25+ and Node 22+.\n\n```bash\ncd web \u0026\u0026 npm install \u0026\u0026 cd ..\nmake build\n./boob-o-clock -addr :8080 -db ./boob-o-clock.db\n```\n\n### Access from your phone\n\nOpen `http://\u003cyour-server-ip\u003e:8080` in Safari and tap **Share → Add to Home Screen**. The app launches fullscreen like a native app.\n\n\u003e **Note:** The PWA service worker requires HTTPS on non-localhost. For local network use, accessing via IP on HTTP works fine — you just won't get offline caching. To enable HTTPS, put a reverse proxy (Caddy, nginx) in front with a self-signed or Let's Encrypt cert.\n\n## Develop\n\n```bash\n# Install frontend dependencies\ncd web \u0026\u0026 npm install \u0026\u0026 cd ..\n\n# Run Go backend on :8080 and Vite dev server on :5173\nmake dev\n\n# Open http://localhost:5173 — hot reload for frontend, API proxied to Go\n```\n\n### Seed data\n\n```bash\ngo run ./cmd/seed -db ./dev.db          # 8 nights of plausible data\ngo run ./cmd/server -addr :8080 -db ./dev.db\n```\n\nGenerates completed and in-progress nights with varied scenarios: long stretches, multi-wake rough nights, stroller blocks, resettles, poop, breast alternation, and two Ferber nights (Night 1 with two settled sessions, Night 2 with a settled bedtime and an abandoned mid-night session falling back to feed-to-sleep).\n\n### Test\n\n```bash\nmake test              # Go tests (115 tests across 4 packages)\ncd web \u0026\u0026 npx tsc      # TypeScript type check\ncd web \u0026\u0026 npm run lint # ESLint (react-hooks rules)\n```\n\n### Project structure\n\n```\n├── cmd/server/          Entry point, wiring, embed\n├── internal/\n│   ├── domain/          State machine (13 states, 41 transitions, zero deps)\n│   ├── store/           SQLite persistence (pure Go, no CGo)\n│   ├── reports/         Stats, timelines, trends, breast tracking, Ferber session derivation\n│   ├── api/             REST handlers\n│   └── web/             Embedded frontend (go:embed)\n└── web/                 Preact + TypeScript + Vite source\n```\n\n### API\n\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/api/session/current` | Current state + valid actions |\n| POST | `/api/session/start` | Start a new night (optional Ferber config) |\n| POST | `/api/session/event` | Record an event |\n| POST | `/api/session/undo` | Undo last event |\n| GET | `/api/nights` | Night list with stats |\n| GET | `/api/nights/:id` | Night detail with timeline |\n| GET | `/api/trends` | Trend data with moving averages |\n| GET | `/api/export/csv` | Download all events as CSV |\n| GET | `/healthz` | Health check (DB ping) |\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliviro%2Fboob-o-clock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fliviro%2Fboob-o-clock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliviro%2Fboob-o-clock/lists"}