- Deleting a moment now shows a custom in-app confirmation modal instead of the browser's native confirm dialog, whose auto-generated title bar read as unfinished. Cancel (outline) and Delete (filled, rose) match the approved prototype, with no change to the delete logic or the 7-day soft-delete window itself
- Timeline's deleted-entries banner now reads “Recently Deleted (N) · Tap to restore” instead of “N deleted entries · tap to restore,” so it actually names the section the confirmation modal points to
Product case study · shipped in 2 weeks
Built out of need, curiosity, and the opportunity to learn and experiment. Handy every day since, especially at 3 am.
Nestlog is the baby log app my fiancée and I have been using since our first weeks home with our newborn baby boy. Every feed, nappy, pump, and breastfeeding session is synced across our various devices around the house the moment it's logged. Easy to use. Quick to log. Handy EVERY.SINGLE.TIME.
Vision
A log, not a database
I knew there were other applications available that could do what we needed, but we didn't even bother looking; for me, it was very simple. I wanted to build this app for us, and I wanted to get better at building with AI.
Problem
A paper tracker was the starting point; it is simple, easy and quick to fill. However, as the data grew rapidly, it got harder to interrogate, and it would only get worse. After a while, paper stops being sustainable: keeping it, reading it back, digging into a specific date you need to check, and storing enough pages. It becomes a hassle.
Approach
A narrowly scoped application, built to mirror the paper tracker's simplicity: log a feed, a nappy change, a pump or breastfeeding session, but with the benefits an app brings: no growing A4 pages, and worrying they're getting mixed or damaged, and most importantly, being able to look back and interrogate the data with ease. It also had to work across all the devices around the house (an Android phone, an iPhone, an iPad). Native builds were out of scope.
Outcome
Shipped an app we've used every day since, continuously updating it with new features, bug fixes, and performance improvements. The opportunity to get better at properly delivering an app, from design and build, to a productionised application built entirely on AI (Claude Code). It also gave me the opportunity to build my own workflow fully reliant on AI, and to keep extending it: automating skills, integrating tools like Linear to track improvements and manage the backlog.
Key features
What it does
Every feature below follows the same workflow, from spec to shipped.
Real-time household sync
Every entry lands on every connected device within seconds. No polling, no refresh button, no stale state.
One-tap logging matrix
Time, amount, who logged it. Every field is editable right where it sits. No modal, no separate save step.
Per-side breastfeed timer
Times Left and Right independently. Survives any number of pauses and switches, and stays live across both devices.
Pump tracking
Its own moment on the timeline, whether or not there's a feed logged at the same time.
Reports & trends
Stat cards, day-by-day charts, and a full daily summary table, filterable by any date range.
Installable PWA
Add to home screen and it launches fullscreen with its own icon. A service worker keeps repeat loads fast without ever caching your data.
Household invites
One shareable code brings a partner or caregiver in. Native share sheet, no account-linking faff.
Notes on any entry
A tap opens a focused editor to read, write, or delete. No keyboard popping up just to glance at what's already there.
Full timeline & history
Every entry we've ever logged. Filterable by type, grouped by day, paginated so months of history don't choke the page.
Recoverable deletes
Deleting a moment is a 7-day soft-delete, not a permanent one. A banner surfaces what's recoverable, and how long it's got left.
Bottle, breast, or both
Log a bottle, a breastfeed, or both for the same feed. Independent toggles, matching how feeds actually happen.
Origin story
One piece of paper on the fridge, then an app
From a real need to experimentation and curiosity to continuous delivery and improvement.
We had a baby
Home from the hospital and straight into feeding and changing. No system yet. Just doing it.
The midwife's first questions
Next day, the midwife asks how many nappies, and their volume, and how often we're feeding, and how much. We know the answers off the top of our heads. But only roughly. Estimates, not data.
Start a paper tracker
One piece of paper on top of the fridge. It works, but it reads more like notes than a log. Something you do constantly deserves a bit of standardisation. Easier to write, easier to read back.
Paper tracker v2.0
A preset format built around exactly what we need to know. Feed, poo, pee, which day, what time, plus a notes line for anything else.
Tracking becomes fast and easy
Now we can answer any question in seconds. When he last fed, how long since. Quick, precise, and the midwife visits get a lot easier.
The paper tracker hits its limit
V2.0 works perfectly, right up until the data outgrows it. Spotting patterns (how often he eats on average) and answering the same questions, especially for his mum, gets harder, not easier.
Build an app with Claude Code
Went live on the 20th of July. Used every single day since.
Continuous iteration
Bug fixes, small enhancements, new features. Added constantly, based on what the two people actually using it (Jen and I) need next.
Workflow
Scoped in Claude Project. Built in Claude Code. Organised, prioritised, and tracked in Linear
Built through continuous iteration based on our evolving needs, with a big focus on automation of repetitive tasks (to make my life easier as a solo builder).
Project chat
An idea gets a conversation and a spec
Every change starts in a Project chat, not a ticket. Once it's real, a handoff skill versions it, uploads to Drive, and finds or creates the Linear ticket, labelled Ready to Build.
Claude Code
One prompt into a real session
The final prompt lands in a fresh Claude Code session, which reads the repo's own CLAUDE.md rather than working from a paraphrased description.
Claude Code
New branch, built and verified
A fresh branch every time, never a reused one. Built against a dev preview, then lint, typecheck, test, and build all have to pass before anything's pushed.
GitHub
A real PR, a real diff
Opens against the production branch with a genuine Vercel preview URL, never a guessed one. I review the actual diff before anything merges.
Vercel
Merging is the deploy
No staging gate sits between them. Once it's approved, merging to production and shipping are the same action. Verified once the deploy comes back READY.
Linear
The loop closes, periodically
Shipped tickets sit in CHANGELOG.md's Unreleased section until it's actually time to cut a version. Release notes and screenshots go out, tickets move to Done.
Not every step moves forward: the two loops
A review surfaces something unrelated to the ticket at hand. It gets its own new ticket and its own new branch, not folded into the PR already open.
Shipped tickets sit in CHANGELOG.md's Unreleased section until it's actually time to cut a version. Never automatic, never assumed.
The full workflow diagram
View the full workflow diagram 6 phases, 2 loops
%%{init: {'theme':'base', 'themeVariables': {'background':'#FBF7EC','primaryColor':'#FFFDF8','primaryTextColor':'#2A2A26','primaryBorderColor':'#CFC4A9','lineColor':'#6B6A63','tertiaryColor':'#FFFDF8','fontFamily':'IBM Plex Sans, sans-serif','fontSize':'14px'}}}%%
flowchart TD
subgraph P0["0 · IDEA + SPEC, Project chat"]
A1["Discuss the fix/feature,
build a prototype"]
A2["momentini-handoff skill:
version + upload to Drive,
find/create JOS-NN,
label → Ready to Build"]
A3["Final Claude Code prompt"]
A1 --> A2 --> A3
end
subgraph P1["1 · HANDOFF"]
B1["Paste prompt into a
Claude Code session"]
end
subgraph P2["2 · IMPLEMENT"]
C1["New branch
(never reuse an old one)"]
C2["Build + verify
(dev-preview + Playwright)"]
C3["lint · tsc · test · build"]
C4["Commit + push"]
C1 --> C2 --> C3 --> C4
end
subgraph P3["3 · REVIEW"]
D1["Open PR → production branch"]
D2["Joseph reviews the diff
(real Vercel preview URL)"]
D3{"Approved?"}
D1 --> D2 --> D3
end
subgraph P4["4 · MERGE + SHIP"]
E1["Merge, Vercel auto-deploys,
no staging gate"]
E2["Verify deploy READY"]
E3["Ticket → Done, labeled +
PROJECT_LOG.md updated"]
E1 --> E2 --> E3
end
subgraph P5["5 · RELEASE CUT, periodic"]
F1["Claude checks in:
time to cut a release?"]
F2["Unreleased → dated
CHANGELOG.md section,
version confirmed w/ Joseph"]
F3["Generate release-notes PDF
+ screenshots"]
F4["Send via chat + attach to
ticket(s) → Done"]
F1 --> F2 --> F3 --> F4
end
A3 --> B1 --> C1
C4 --> D1
D3 -->|Yes| E1
D3 -.->|"Changes requested"| C2
D3 -.->|"Found a follow-up → new ticket"| C1
E3 -.->|"batched, not per-ticket"| F1
style P0 fill:#F5E6C8,stroke:#C98A2E,stroke-width:1.5px,color:#2A2A26
style P1 fill:#FFFDF8,stroke:#CFC4A9,stroke-width:1.5px,color:#2A2A26
style P2 fill:#DDE9EE,stroke:#3F7391,stroke-width:1.5px,color:#2A2A26
style P3 fill:#F5E3EA,stroke:#B15E7C,stroke-width:1.5px,color:#2A2A26
style P4 fill:#E4EDE8,stroke:#4F7566,stroke-width:1.5px,color:#2A2A26
style P5 fill:#EAE4F2,stroke:#7C6A9E,stroke-width:1.5px,color:#2A2A26
style D3 fill:#F5E3EA,stroke:#B15E7C,stroke-width:2px,color:#2A2A26
classDef node fill:#FFFDF8,stroke:#CFC4A9,stroke-width:1px,color:#2A2A26
class A1,A2,A3,B1,C1,C2,C3,C4,D1,D2,E1,E2,E3,F1,F2,F3,F4 node
Release notes
Currently available releases
Every version, from first commit to the release shipped this week. Each has its own scoped changelog and, where relevant, screenshots of what changed.
- Bottle/Pump mL amounts and the time editor could silently fail to save on Android Chrome, which doesn't reliably fire a blur event when the on-screen keyboard is dismissed via its own control rather than a tap elsewhere. The mL fields now also commit on a short debounce after typing stops, and the time editor force-blurs on Enter as a lighter safety net
A silent-save fix with no visual change, nothing to see, which is the point.
- Home's entry list is now day-aware instead of a flat entry-count cap. Every entry from today, in full, plus the last 3 entries from the previous calendar day only, for continuity when checking the last logged moment overnight
- Today and Yesterday both get an equally prominent sage-green divider with extra breathing room above it, so the boundary reads clearly even scrolling quickly
- Since the divider now states the day, each entry's field only shows its time, not the full date. Tapping it still opens the full date+time editor
- Times could render in 24-hour format instead of AM/PM depending on the viewer's device locale. AM/PM is now forced everywhere a time displays, regardless of locale
- Deleting a moment (via the checkbox uncheck, the phone card's ×, or bulk select-and-delete) is now a 7-day recoverable soft-delete instead of a permanent one
- A banner inside Timeline shows the number of recoverable moments and appears only when there's something to restore, opening a "Recently Deleted" screen listing what was deleted, by whom, and how long it's got left
- Each deleted moment restores and displays as one whole card. A pee + poo logged together restores together, matching how it looked before deletion
- Restoring flashes the card back into its correct chronological position on Timeline, with a smooth transition on both ends
- Reports page capped out at an old date instead of showing entries through today. A single unpaginated database query silently dropped everything past its first 1,000 rows, cutting off the newest entries once a baby passed that count
- Reports now pages through the full entry history in batches until nothing's left, so every entry loads no matter how large the log gets
A data-fetching fix with no new UI of its own. No data was ever at risk, this only affected what one screen displayed.
- Per-side breastfeeding timer (Right/Left), an inline panel, no modal, with Left/Right start-pause buttons that auto-pause each other
- Session stays open across any number of pauses/switches until an explicit "End Session"
- Elapsed time computed from a stored start timestamp, not counted tick-by-tick. Stays correct even after the app is backgrounded
- In-progress sessions sync live across devices, including a read-only ticking view on Timeline
- Reports: two new stat cards, a Right-vs-Left chart, and three new Daily Summary columns
- Reports charts no longer force the page to scroll sideways on phones once a range has enough bars. Both charts scroll horizontally inside their own card instead
A layout fix with no new UI of its own. The chart behaves correctly rather than looking different.
- Realtime channel was being torn down and rebuilt on every poll tick, not just genuine reconnects. That churn was plausibly destabilizing the realtime tenant itself
- Poll now only refetches; the channel rebuilds only on an actual "we're back" signal
An under-the-hood sync fix, nothing to see, which is the point.
- The pumped-volume chart now shows session count alongside volume. A day with lower volume but far more sessions reads at a glance
- Daily Summary table gets a new "Pump sessions" column; the whole table is now center-aligned
- Notes moved from a cramped inline field to a focused modal for reading, writing, editing, and deleting
- Doesn't auto-focus the textarea, so opening it to read a note no longer pops the mobile keyboard
- Save stays disabled until the text genuinely differs from what was loaded
- iPad PWA no longer pops the native date/time picker open on relaunch
- Entries from another device could go missing until force-close. Home now resyncs on every plausible "we're back" signal and polls every 20s while open
Two reliability fixes, no new UI.
- Pump tracking (its own Pump chip on Home and Timeline), logged as an independent entry
- Reports: Pump sessions and Total pumped stat cards, a pumped-mL-by-day chart
- Timeline: a Pump filter chip alongside Bottle/Breast/Poo/Pee
- Installable as a PWA. "Add to Home Screen" launches Nestlog fullscreen with its own icon
- A minimal service worker caches static assets for faster repeat loads. It never caches data, so logged entries are always fresh
- Phone-width card layout for Home and Timeline, replacing the horizontally-scrolling table
- Home's cards are fully editable with a per-card delete control
- iPad and desktop keep the existing table layout, unchanged
- Feed logging splits into independent Bottle and Breast toggles: either, both, or neither, matching how real feeds happen
- Reports: split stat cards, a bottle-only mL chart, a grouped Bottle vs. Breast chart
- Email/password and Google sign-in, with invite-code household onboarding
- Matrix-style Home screen: one row per moment, every field editable in place, no modal
- Realtime sync, Timeline history, and a full Reports tab with stat cards, charts, and date filters
Roadmap
What's Next
Pulled straight from the live backlog in Linear.