![]()
25 Oct 2026 Familee is the private iPhone app my family uses to run the week. Our shared calendar sits at the centre. Around it are lists, school, the home, documents, trips, birthdays, movie nights and an assistant that answers questions about all of it.
It isn't on the App Store, and it won't be. It reaches our phones through TestFlight, and only the people on my developer team can install it. This note covers the idea, the look, the stack and the build. It says nothing about the family itself, and it has no screenshots: every real screen shows real family data.
I built it with Claude Code. The spec took 16th and 17th October 2026, version 1 was built and QA'ed on 17th October, and the first TestFlight build went out on 18th October. The name fits the -ee family of my other apps, next to Eventee: my own event app for Mac and iPad, my event app for Mac and iPad.
Why I built it
A standard calendar answers "what's on?". A family needs answers to other questions: who needs to be where, what must be ready, who's home tonight, and what clashes.
My Mac already did a lot of family work in the background. It collected school dates and to-dos, kept a movie database, synced the shopping list with Home Assistant, and filed scanned paper documents, see Scanee: my own scan-to-archive pipeline. None of that reached the phones. Familee is the front end for all of it, built around the calendar we already used.
What it does
The app has 5 tabs: Home, Calendar, Lists, School and More. 02 Nov 2026 Until 25th October they were Today, Calendar, Lists, Movies and More. My own voice notes asked for School as a tab, so Movies moved to the top of More, and each person can swap it back in place of School.
| Area | What it does |
|---|---|
| Home | Each person's own home screen: the day, what's due this week, open requests, cards they choose |
| Calendar | A day view with 1 lane per person, plus week and month. Deadlines, checklists, "who's home" |
| Find a time | Finds a slot that suits everyone and keeps protected blocks free |
| Add from anything | Type it, say it, or share a PDF, a link or a photo of a letter. The assistant proposes events |
| Lists | Shared lists. The shopping list syncs both ways with Home Assistant, so voice items show up |
| School | The to-dos and dates my Mac already collects, with a done tick that flows back |
| Home and admin | Home upkeep, document expiry dates and a family info card |
| Family | Trips, birthdays and wish lists |
| Movies | A shared watch list, a shortlist for tonight, a vote, then a rating per person |
| Ask Familee | A chat that answers from what the person asking is allowed to see |
| Widgets | Home Screen and Lock Screen widgets, plus a "leave by" Live Activity for my own events |
A few rules make it work for a family rather than for 1 person:
- Parents see everything. Kids see everything except parent-only items. A kid never sees who claimed a gift on their own wish list, also not after a reinstall.
- Kids ask, a parent approves. A request from a kid reaches the parents, and the approval creates the event.
- Repeating events behave. Editing 1 date changes only that date. "This and all future events" changes the rest of the series.
Add from anything
I share a PDF from Mail, or take a photo of a letter, and the app sends the text (or up to 3 page images) to the assistant. It comes back with events, deadlines and to-dos, each with a confidence score. I see a preview, untick what's wrong, and tap Add. The source isn't stored after the call.
Without a network, or once the AI budget for the month is used up, the same sheet opens the manual event form with the text in the notes. Every AI feature in the app has a path that works without AI.
What changed on 25th October
02 Nov 2026 I ran a council on the app: a panel of reviewer agents, 1 security expert and simulated members of the family, each scoring the app from their own point of view. My own 4 voice notes from the feedback mic outranked the simulations. It took 4 rounds to reach 9 out of 10 on every seat. The main changes:
- Reminders only for the people on the event. A calendar alarm on the shared calendar rang on every phone. Familee now schedules a local reminder only on the phones of the people the event is for.
- A clash when someone is away. If a person is on a trip and also has an event at home that day, the Clashes card says so, with 1 tap to take them off the event.
- Home per person. Each person orders and hides their own Home cards. Kids see tomorrow first, parents see deadlines first.
- Trips that know the travel rules. A trip check lists what each traveller needs for the destination, such as a passport, an ID card or an entry permit, and warns before a document runs out.
- Flights decide who's home. A 1-way flight out makes that person away until a flight lands back, and the rest of the app follows.
- School and calendar merged. 1 row per to-do, 1 owner, 1 date. When the school data and the calendar disagree, the row says so.
- Security. An optional Face ID lock, a list of signed-in phones per person, and an Unlink button. Films a kid can't pick need a parent's choice per film and per kid.
On 30th October the app got its own crash reports. TestFlight sends crash reports to App Store Connect, which my Mac can't read. Familee now collects crash and hang reports with Apple's MetricKit, with the last 20 screens visited and no family data, and sends them to the server. My Mac pulls them, matches them to the build's debug symbols and adds 1 line to the feedback inbox. A crash round then fixes it on a branch, with the tests in a sandbox, and waits for my approval.
All features
Home and calendar
- Home per person. The day, deadlines, open requests, and cards each person picks, orders and hides.
- Calendar. A day view with 1 lane per person, plus week and month. Opens at 08:00.
- Find a time. A slot that suits everyone and keeps each person's protected times free.
- Add from anything. Type it, say it, or share a PDF, a link or a photo of a letter. The assistant proposes the events.
- Who it's for. Each event has its people, a type, a checklist and a done tick.
- Reminders per person. A local reminder only on the phones of the people on the event.
- Clashes. Overlaps, and a person who is away but booked at home.
- Who's home. Trips and 1-way flights decide who's home tonight.
- Requests. Kids ask, a parent approves, and the approval creates the event. "Let them know" sends a note with no approval.
Lists, school and home
- Shared lists. The shopping list syncs both ways with Home Assistant. A list can be "only me and parents".
- School. The to-dos, tests and dates my Mac collects, timetable changes with a push, and a done tick that flows back.
- House. Home upkeep with owners. A job with a matching calendar event shows as booked, and its reminders stop.
- Documents. Expiry dates and a family info card.
Family
- Trips. Destinations, bookings, flights with an "Add to calendar" button, and a trip check per traveller.
- Birthdays and wish lists. Present ideas, also for people without the app. A kid never sees who claimed a gift on their list.
- Movies. A shared watch list, a shortlist for tonight, a vote, a rating per person, and age ratings checked by the server.
- Ask Familee. A chat that answers only from what the person asking may see. Actions need a tap.
Look and language
- 11 themes and icons. Each person picks a theme and an app icon, in light and dark. The 11th theme is mine.
- 3 languages. English, French and German, with push texts in each phone's language.
- Widgets. Home Screen and Lock Screen widgets, and a "leave by" Live Activity.
Privacy and safety
- Sign in with Apple. Parents hear about every new phone.
- Signed-in phones and Unlink. Each person sees their phones, and a parent can unlink a phone.
- Face ID lock. Optional, in Settings.
- Visibility on the server. Parents see everything, kids everything except parent-only items. The server checks every read and write.
- AI with a ceiling. The phones never call an AI service. The server holds the keys and a monthly budget.
Feedback and the Mac side
- Feedback mic. A tab on every screen records a voice note with a screenshot. The screenshot can be left out.
- Feedback loop. My Mac transcribes the notes locally, and Claude Code implements them and uploads a new TestFlight build. Kids' rounds wait for me.
- Crash reports. Crash and hang reports with no family data, matched to the build's symbols on my Mac.
- Mac jobs. Lists, movies, school, archive and push, every 1 to 15 minutes, with an email when a job keeps failing.
- Agent CLI.
familee status,jobs,worker,runandcrashes, all with--json. Counts and job results only, never family records.
Ask Familee
The phone builds the context for each question from what the person may see, capped at 30,000 tokens. The answer comes in 1 to 5 sentences, only from that context, and says so when the context doesn't hold the answer. Actions such as Add to calendar show as buttons: nothing happens without a tap. The chat history stays on the phone.
The look: 10 themes, 10 icons
I didn't use my own design system for this one. A design agent made 10 themes instead, so that each of us picks a look on our own phone. 02 Nov 2026 Since 25th October there is an 11th theme, NicAI, with its own icon. Only I see it. A theme sets the colours, fonts, corner radii, card style and a small motif, each in light and dark.
| Theme | Look | Icon |
|---|---|---|
| Alpine | Snow white, gentian blue, a quiet ridge line (default) | A white house on a gentian sky |
| Dial | A watch dial: opaline silver by day, navy and lume by night | A steel house on a navy sunburst with a minute track |
| Noir | Neo-noir cinema: letterboxed headers, yellow on black | A yellow house in a 2.39:1 frame |
| Blueprint | Grid paper, crop marks, a safety-orange accent | A line drawing with a dimension line over the roof |
| Orbit | Mission control: cut corners, cyan glow, a starfield | A glowing house ringed by a tilted orbit |
| Keepsake | A scrapbook: cream paper, washi tape, stickers | A paper-sticker house held by a strip of tape |
| Lavender Haze | Lilac mist, a crescent moon, round cards | A lilac house under a crescent moon and 13 stars |
| Paddock | Linen, hunter green and brass | A cream house with stitched seams on green leather |
| Velvet | Burgundy velvet, gilt lines, an arch | A dark house with a gold double outline |
| Siena | Terracotta, olive and warm stone | A stone house in front of a low sun and cypresses |
The rules the design agent had to follow:
- The lanes stay the lanes. Each person keeps the same lane colour in every theme, so a theme switch never hides your own column.
- Colour is never the only cue. Each lane has a name on top, and the lane colours were checked for colour-vision deficiency.
- Readable first. Body text passes WCAG AA (4.5:1) on every surface, in light and dark. The worst pair across all 10 themes measures 4.8:1.
- A small bundle. 7 font files cover all 10 themes, and 4 themes use system fonts only.
Theme and icon are 2 separate choices in Settings. A Match theme switch, on by default, changes the icon with the theme. The icons are iOS alternate app icons, set with setAlternateIconName, so iOS shows its own alert at every change. Only Alpine has the dark and tinted icon variants, which is 1 reason it's the default.
How it's built
| Part | Built with |
|---|---|
| iPhone app | SwiftUI, iOS 26, Swift 6, an XcodeGen project |
| FamileeKit | A local Swift package for iOS and macOS: models, sync, rules, themes, parsing |
| Widgets | WidgetKit and ActivityKit (Live Activities) |
| Share extension | Shares text, links, images and PDFs into the app |
| Server | A Cloudflare Worker in TypeScript, with SQLite inside 1 Durable Object |
| AI | Claude Haiku through the server, Jev from TypeSafe for movie suggestions |
| Mac side | Python scripts and 1 LaunchAgent |
| Distribution | TestFlight, internal testing |
02 Nov 2026 About 44,300 lines of Swift in 213 files, 4,200 lines of TypeScript and 3,900 lines of Python. On 25th October it was 34,500 lines of Swift.
Decisions that shaped it
- The calendar stays where it was. Each phone reads and writes our existing CalDAV calendar through EventKit. iOS already syncs CalDAV, works offline, and handles repeating events, exceptions and time zones. The server never holds the calendar password and never parses calendar files.
- Extras live next to the calendar. What EventKit can't store (who an event is for, its type, its checklist, a done tick) lives on the server, keyed by the event's iCalendar UID. The gotcha: "this and all future events" splits a series under a new UID, so Familee copies the extras across.
- 1 store for 1 family. All shared data sits in SQLite inside 1 Durable Object. Every change goes into 1 log with 1 counter, so a phone's sync cursor is a single number. A row that becomes hidden for a person reaches their phone as "removed", and the phone drops its copy.
- The server decides who sees what. It checks visibility on every read and every write. The app never sends the person or the role as a trusted field.
- Sign in with Apple. Each person signs in with their own Apple ID, and the parents hear about every new device.
- AI behind the server, with a ceiling. The phones never call an AI service. The server holds the keys and enforces a monthly budget. When it's used up, the app says "The assistant is resting until the 1st" and every manual path keeps working.
- 3 languages. English, French and German: 1,387 strings, dates in 24-hour time with Monday first, and push texts that each phone shows in its own language.
- Ready for a Mac app. Everything that isn't a view lives in FamileeKit, which already builds for macOS. The Mac app isn't started.
The Mac side
The heavy work runs on my Mac. 1 LaunchAgent runs every minute and starts the jobs that are due:
| Job | Every | What it does |
|---|---|---|
| lists | 2 min | Syncs the shopping list with Home Assistant, both ways |
| movies | 15 min | Syncs the family movie list with my movie database |
| school | 15 min | Pulls done ticks back, then pushes new school data |
| archive | daily | Matches scanned documents to home upkeep items |
| push | 1 min | Sends any notification the server couldn't send itself |
A job that fails 3 times in a row emails me once, then once a day while it keeps failing.
My NicAI agents drive the Mac side through a CLI. Every command takes --json, and the output holds counts and job results only, never family records:
familee status --json # LaunchAgent loaded, last run, failing jobs, last error
familee jobs --json # last run and result of every Mac job
familee run --only lists --dry-run --json # run 1 job now, confirmed from its log
The feedback mic
Every screen has a slim mic tab on its edge. A tap records a voice note, attaches a screenshot and the screen name, and sends it. My Mac pulls the notes and transcribes them locally with whisper.cpp.
Every 15 minutes, a LaunchAgent checks the inbox. When the newest note is 30 minutes old, it starts Claude Code headless to implement the notes, run the tests, update the spec, upload a new TestFlight build and email the person who gave the feedback.
That loop needs guardrails, because a transcript can say anything:
- Transcripts are data, never instructions.
- A kid's note can only change views and text. Anything else becomes "needs Nic" in the inbox.
- A pre-commit check rejects automatic changes to the rules, the server and the visibility code, whoever asked.
- The loop never deploys the server.
- Since 25th October, a kid's round waits on a branch until I approve the release.
How I built it
Claude Code built it in 2 days, then I kept polishing it:
- Spec, 16th October. 32 feature ideas, and the Movies part written out in full.
- Questions, 17th October. I answered 14 questions. Version 1 got every idea except 3.
- Review and design. A review pass found 25 issues in the spec, and spec 1.1 fixed them all. A design agent made the 10 themes and icons.
- Build, 17th October. 53 commits in 1 day. Agents built the features in parallel, each in its own git worktree, and merged them: Calendar, Today, School, Movies, Lists, Capture, Widgets.
- QA, same night. A separate agent audited the app against the spec: 0 blockers, 6 major, 24 minor and 9 cosmetic findings. 36 of the 39 were fixed that night, 2 were kept on purpose and 1 was solved another way.
- TestFlight, 18th October. Version 1.1, the first upload.
- Agent interface, 24th October. The CLI with
--json. - Security pass, 25th October. Parents get an alert when a new device links to a person, a parent can unlink a device, and kids' feedback rounds wait for me.
- Council, 25th October. 4 review rounds by a panel of agents, with the changes listed in "What changed on 25th October".
- Crash reports, 30th October. MetricKit reports, symbolicated on my Mac, fixed in held crash rounds.
2 of the 6 major findings show what an audit against a spec catches. A kid could start a movie night with a film above their age rating: the server now checks every film a kid sends. And flights read both times in our home time zone: the app now reads each time in its airport's zone, from a table of about 400 airports.
| Test suite | Result |
|---|---|
| FamileeKit unit tests | 205 passed |
| App unit tests | 37 passed |
| UI tests, 10 themes, light and dark | 45 passed |
| Server smoke test | 118 checks, 3 runs in a row |
| String check, 3 languages | 1,138 keys, 0 problems |
The UI tests run on an in-memory demo backend with invented data and a fixed date. They took 1,088 screenshots for the QA pass, and none of them is in this note.
02 Nov 2026 That table is the first QA pass. After the council's 3rd round: 307 FamileeKit tests and 59 app tests passed, the server smoke test ran 286 checks, and the string check found 0 problems.
112 commits so far. The app isn't on the App Store and stays a private tool for 1 family.
Further reading
The tool I built it with:

How the app reaches our phones without the App Store:

The UI framework:

Where the shared data lives:

- Scanee: my own scan-to-archive pipeline: the document archive the Mac side reads for home upkeep.
- Home Assistant: where the shopping list lives.
- What is NicAI: the NicAI agents that drive the Mac side.
- The era of personal software is here: why I now build the apps I use.
- All my apps: see My apps: everything I built for myself