Nate Moss Southern Pines, NC

126 days from first commit to a live App Store product.

Built solo. Web and iOS at full feature parity, taking real payments. Here is how it went, including the parts that went wrong.

A mother and her daughter at a wall-mounted iPad in a kitchen. The girl is tapping the last unchecked item on her morning list: brush teeth, make bed, get dressed, eat breakfast, with three of the four already done.
Poppycal on a wall-mounted iPad. The primary device, and the reason for most of the design decisions below.

Day 000

The problem

A family runs on a calendar, but the calendar is never in one place. One parent lives in Google, the other in Outlook, the kids' school sends iCal, and nothing writes back to anything else.

Most family apps solve this by importing your calendar and hoping you switch. Poppycal syncs two ways with Google, Apple, and Outlook at the same time, so nobody has to move.

It is built for a tablet on the kitchen wall, which turned out to change almost every design decision in the product.

Day 126

What shipped

Calendar with true two-way sync. Chores and star rewards. A PIN-locked Kid Mode. Meal planning with a recipe importer and a cooking mode. Grocery lists that sort by supermarket aisle. Homeschool tracking with compliance exports for state filing. Babysitter mode. Photo screensaver. iOS home screen widgets.

Every one of those ships on both web and iOS. No "coming to mobile later."

A week calendar, Sunday to Saturday, with each family member's events in their own colour: swim lessons, art class, ballet, soccer practice, date night, and a birthday party.
Calendar
Four children side by side, each with a star total and their own morning, afternoon, evening, and chore lists. One column reads All done.
Chores and rewards
A week of meals laid out as a grid, with breakfast, lunch, dinner, and snack for each day from Monday to Friday.
Meal planning
A homeschool week, Monday to Friday, showing each child's subjects and how many assignments are finished: algebra, literature and history for one, maths, reading and science for the other.
Homeschool
A grocery list sorted into aisles like produce, dairy and pantry, with bought items struck through, plus tabs for other lists and a button to send the whole thing to Instacart.
Lists and groceries
Kid Mode, locked to one child. The navigation drops to four items and the screen shows only Olivia's evening tasks: put on pyjamas, tidy bedroom.
Kid Mode

Watch the full tour → Four minutes, silent, every feature.

The interesting part

Four decisions

Shipping is the easy thing to show. These are the four calls I would want to be asked about.

01

Arguing with Apple instead of paying them

Apple rejected Poppycal twice. The second rejection cited Guideline 3.1.1 and demanded In-App Purchase for subscriptions, which costs 15 to 30 percent of every subscription forever.

Apple's own rejection message offered a way out: the US storefront link-out allowance, letting the app link to an external purchase page. That looked like the easy path.

It was a trap. Adding a purchase link would have disqualified the app from Guideline 3.1.3(f), the free stand-alone apps exemption, which requires an app to have no purchase calls to action at all. It would still have failed 3.1.3(b), which demands IAP. Taking the path Apple suggested meant failing both rules instead of one.

So I argued the 3.1.3(f) exemption directly, and added neither IAP nor a link.

Approved two days later. The app ships with no purchase links anywhere, which is precisely what makes it approvable.

02

A bug that was actually an architecture problem

Kid Mode is a PIN-locked kiosk that limits what a child can see and do. It shipped with a defect: a kid could reorder the chore board. That sounds small. It broke the entire promise of the feature.

The cause was not a coding mistake. The rule defining "is this session locked" had been written by hand into three separate iOS files instead of imported from the one shared definition. Over time the copies drifted, and iOS quietly lost a gate that the web app still had.

Fixing the bug was not the fix. I deleted the redundant concept so Kid Mode became one flow instead of two, then built a CI check that fails the build when web and mobile grow a new copy of the same logic.

The honest part: that gate cannot catch omissions. Three of the four parity breaks in this incident were iOS missing something web had. Absence has no duplicate to detect. "Does iOS actually do everything web does here" is still a human question, and I still have to ask it.

03

Two weeks of shipping nothing

In May the web app was live and working, and I decided to build iOS.

The fast move is to start the iOS app. Instead I spent about two weeks moving the entire codebase into a monorepo with a shared business logic package first. No features shipped in that stretch.

The iOS app was scaffolded on May 13 and reached parity with a large, mature web product within weeks. The two apps share zero rendering code and one hundred percent of their rules.

It still was not enough on its own, which is why decision 02 exists.

04

Saying no to the most requested feature

Users asked for family group chat. Competitors ship it.

I researched it and said no. What families wanted was not another place to send messages. They wanted the context that belongs to an event to live on the event.

So I shipped comments on events instead. It is one of the smallest features in the app and it covers the job people were hiring group chat to do.

How

How it was built

I am not an engineer. No CS degree, no prior engineering job. Poppycal was built by directing an AI coding agent from written tickets: 181 tickets, 342 pull requests, and a review on every one before it merged.

I set up the quality gates that made that safe, including a complexity ceiling that can only move down, the duplication check described above, and a written definition of done covering accessibility, touch targets, and error handling.

That is the how. The what is everything above it.

Running a security audit before launch instead of after, reading Apple's guidelines closely enough to win an appeal, deciding a duplication bug was an architecture problem, refusing the most requested feature: those were judgment calls. They would have been the same calls if someone else had typed the code.

Receipts

By the numbers

First commit to App Store
126 days
First commit to live payments
107 days
Pull requests merged
342
Tickets shipped
181
Automated tests
1,624
Database tables
55
Checks per pull request
6
Lines of application code
211k
Contributors
1

211,000 lines across 126 days is about 1,675 a day. That is not a typing speed. That is what directing an agent looks like when the specs are clear and the review gate holds.

Launched July 29, 2026. A security audit before launch found 51 issues across 13 phases. 42 were fixed before shipping, including three critical: an OAuth CSRF, an admin endpoint leaking password reset tokens, and calendar credentials sitting in the database in plaintext.

The day job

Shelterluv

I have spent the last five years at Shelterluv, a B2B SaaS platform used by more than 2,000 animal shelters and rescues. I own new customer data migration, which means building the tooling that gets a shelter's entire history out of whatever system they were on and into ours. The framework I built cut per customer data prep from days to under an hour and has run across hundreds of onboardings.

I also rebuilt their help center over about a year, from 800 articles down to 250 plus 100 videos, and spent six months embedded with the product team during a platform rewrite while holding that role.

I also run a personal Flask app on a home server that tracks my house, my fitness, and my kitchen. It is not for sale and never will be. I build things whether or not anyone is paying me.