Baby Suite: three small apps, three sync models
Three web apps for the first months with a baby: a contraction timer, a feed, sleep and diaper tracker, and a pelvic-floor exercise trainer. Each syncs between phones with a conflict model chosen for its data. We built them for our own use, and the tracker runs in daily use.
- Status
- In daily use
- Frontend
- Plain JavaScript, no framework or build step
- Backend
- Cloudflare Workers and KV, now self-hosted on Node.js
- Source
- Private — walkthrough on request
What it does
A sync model per app
The contraction timer syncs its whole state and the last write wins, since one person does the timing. The tracker merges entry by entry with deletion markers, so two caregivers logging at once never lose a tap. The trainer only ever appends sessions.
Web Push with no dependencies
VAPID signing and aes128gcm payload encryption written directly on WebCrypto, 87 lines in total, and checked with an offline encrypt and decrypt round trip.
Alerts with the app closed
Alert rules are checked on the server every five minutes, per device, with four urgency levels from a silent note to a ringing alarm, and quiet hours.
The free tier as a design rule
Everything was built to fit Cloudflare's free tier. When one cron job was using 87% of the daily KV list quota, we moved push subscriptions into a single record per sync group, so the cron makes no list calls at all, and wrote the quota math into the repo as a standing rule.
Offline first
The tracker and the trainer are installable PWAs with a network-first service worker: they open without signal, and a new version is picked up on the next load.
Snapshots and archives
A daily job snapshots each sync group, keeps 14 days of backups, and moves entries older than 35 days into monthly archives so the live state stays small.
Relevant if you're looking for…
Baby Suite is a private project that cannot be downloaded, so this page is about how it is built and what we can build for you.
- A baby tracker app you can share with a partner: the feed, sleep and diaper log merges entry by entry with deletion markers, so two people logging at once never lose a tap.
- A contraction timer that syncs between phones: it syncs its whole state and the last write wins, since one person does the timing.
- Push notifications from a web app that is closed: the server checks alert rules every five minutes per device and sends Web Push, from a silent note to a ringing alarm, with quiet hours.
- An offline-first web app with sync for your own users: we build small apps like these for clients, choosing the conflict model from the data and doing the quota math before launch.
We build this for clients: Custom software and internal tools
How it works
- 01
Log
Every tap is saved on the phone first.
- 02
Sync
A regular poll sends only what the server is missing.
- 03
Merge
Each app resolves conflicts with the model that fits its data.
- 04
Alert
A server job checks the rules and sends a push, app open or not.
How it's built
Each app is a single HTML page in plain JavaScript, with no framework and no build step. Sync ran on one Cloudflare Worker and KV namespace per app, and every recurring operation was budgeted against the free tier: poll intervals and cron frequency come from the quota math, polling stops while the tab is hidden, and clients skip a write when the server already has the data.
Later we moved the apps to our private cloud infrastructure, as a small Node.js service in Docker. The worker code runs there unchanged, on top of a file-backed stand-in for KV with atomic writes. The old and new stacks ran side by side during the move, and the data was checked identical, entry by entry, before any device switched over.
Engineering highlights
- Web Push in 87 lines of WebCrypto, no libraries
- KV list calls from the cron cut from about 600 a day to zero
- Per-device alert rules, four urgency levels and quiet hours
- Worker code moved to a self-hosted server without changes
Questions
Can I download Baby Suite?
No. Baby Suite is a private project and is not available to the public. We build apps like it for clients.
How do two phones log to the same tracker without losing entries?
The tracker merges each entry on its own and marks deletions instead of dropping them, so taps from two phones at the same moment are all kept. The timer app uses last write wins instead, since only one person does the timing.
Do the apps work without signal?
The tracker and the trainer are installable PWAs with a network-first service worker, so they open without signal. Every tap is saved on the phone first, and a regular poll sends the server only what it is missing.
Want something like this?
Small apps deserve the same engineering as large ones: choose the conflict model from the data, do the quota math before you ship, and add a dependency only when it earns its place.
Get in touch