Bubbyway, the Household App I Wrote for the Two of Us
A self-hosted SvelteKit app for one specific household. Chores and meds and shopping, yes, but also inside jokes and date nights and a wishlist that hides its own state from the person it belongs to. What I learnt building software for two named people rather than for an abstract user base.
There was a Tuesday evening, late last year, when my partner asked me what time the optician was the next morning and I had to scroll through three different apps before I could answer them. The appointment was in a shared calendar, the doctor’s note about which eye drops to bring was in a notes app I half-remembered creating, and the question of whether we had any of the eye drops left was in neither place and not really in my head either. I closed the laptop and we ordered a takeaway and I sat with the slightly tired feeling of running a flat together using tools that did not really know we were running a flat together.
That was the evening I started writing bubbyway. The app is a self-hosted SvelteKit thing that lives on a Raspberry Pi in our hall cupboard, served behind a Cloudflare Tunnel at a small URL that opens on either of our phones and on the laptop in the kitchen. Everything our household runs on lives inside it. The chores and the medicines and the shopping list, the council repairs we have been chasing for months, the appointments and the recipes and the weekly menu, the things we keep meaning to discuss, the inside jokes, the wishlists, the date nights, the small list of things we want to do together while we still can. It is one database, one Node process, one piece of software that has been shaped slowly over months around the actual shape of our actual days.
Why one app rather than a constellation of tools
The honest answer to “why not just use Trello and Google Calendar and a notes app and a shared spreadsheet” is that the integration work is the whole point. The reason I needed one app rather than five is that the things our household has to deal with are not actually five separate things. The recipe pushes its ingredients onto the shopping list. The shopping list knows that oat milk is a staple and re-adds it five days after we bought the last carton. The medicine schedule knows that my partner takes a thing on Sundays and Wednesdays and quietly disappears from the Today view on the other days. The Today view itself shows the overdue chores, the appointments due in the next hour, the meds my partner has not yet ticked, and the chore that snoozed itself to this morning, all in one place, in the order a real morning needs them.
When the integration is doing its job, the app feels less like software and more like a quietly competent third member of the household who keeps track of what we have between us forgotten. The chore I marked done at lunch on Monday rotates to my partner for next Monday, automatically, because the rotation knows there are exactly two of us. The meal planner pushes the ingredients I need for Tuesday’s dinner onto the shopping list, skipping the items that are already there. The wishlist hides its “got it” state from the gift recipient, because the surprise is the entire point of the wishlist, and the app knows that surprises only work if one person cannot see what the other has already bought. None of those features are clever. They are just consequences of writing software for the people you actually live with.
What designing for two named people actually changes
The shape of the app reflects the shape of the household in ways that I think would be very hard to reverse-engineer from a SaaS aimed at thousands. The most obvious one is privacy: the medicines section on the Today view is collapsed by default, with a discreet “X of Y taken” pill, because either of us might glance at the other’s phone over the kitchen counter and a list of medicine names is not always something you want a passing eye to land on. The collapsed-by-default pattern recurs through the app: medicines, occasions, this-week’s-chores. The expanded state is one tap away if you actually want to see it, but the default is to give the page the space to be looked at without revealing more than it needs to.
The chore rotation is a similar example. There are exactly two of us in the reference deploy, so the rotation rotates between two people and nothing more. The codebase is being gently prepared for households with more than two members, and the multi-household roadmap in NEXT_STEPS.md is part of that, but the version that lives in our flat is honestly designed for two. The PriorityPicker has three levels because three is what we needed; the lifetime list has fields for “what was it like” because we wanted somewhere to write down what the trip we took actually felt like once we had taken it; the inside jokes journal has an author attribution because we keep arguing in a fond way about who actually said the thing first, and the journal settles it.
The wishlist is the feature I am quietly fondest of for this reason. Each of us has a list of things we would love. The owner sees their own list, and can add and remove things from it, but never sees the “got” state, because the “got” state is the bit that would spoil the surprise. The other person sees the same list with the full state visible and a quiet tick option that records when the surprise has been arranged. The data model is two booleans and a foreign key. The reason the feature exists is that I could not find a single app on the App Store that understood that the person who writes the wishlist is not the same person who reads it, and the gap between those two perspectives was a hole in every gift-list app I had tried.
Memories, and the small surprise of being known
The “Memories” page pulls from completion records and appointments and inside jokes and date nights and bucket list items and queue items, from around the same date a year ago, with a few days of fuzz around the target date so the page is rarely empty. The first time I opened it, on a quiet morning in February, it showed me the takeaway we had ordered exactly a year ago and a chore my partner had ticked off and a film we had watched together, and I sat at the kitchen counter with my tea going cold and found myself unexpectedly moved by how much of the year had quietly accumulated inside the app without my noticing.
I want to be honest about that, because most of what I write about technical work is about how it functions, and most of what I do not write about is how it feels. The Memories page is the bit of bubbyway that has surprised me the most in actually living with it, not because it is technically interesting (it is a handful of queries against existing tables, filtered by date) but because it turned out to be doing emotional work I had not designed it to do. The app started knowing things about us, and then started reminding us of those things, and that is a different category of usefulness from the chore-tracking and the medicine-logging.
Open source under AGPL
The licence is AGPL-3.0-or-later, deliberately. The project is meant to be self-hosted; if someone modifies it to run as a hosted service, those modifications need to come back into the open. There is no hosted version of bubbyway and there is not going to be one, because the things that make this app good for us are exactly the things that would not generalise to anyone else. The roadmap in NEXT_STEPS.md is about making it possible for another household to fork it and run their own copy without having to read every line of code first, and the unfinished work there is mostly the first-run setup wizard that replaces the hardcoded starter members with a name-and-colour picker, and the configurable household name that replaces the small private nickname the app currently carries.
If you do fork it, the README’s closing line is the right invitation: give it your own colour and your own name where it speaks to you. The accent colour in the reference deploy is #9966cc, which is a colour that means something to my partner and to me and which absolutely does not need to mean anything to anyone else. The name itself comes from a private nickname between us, in the same way the inside jokes feature does, and I am not going to explain it any further than that. Some things in the code that runs my home are allowed to be ours.
What I have actually learnt
The thing that keeps coming back to me, as I look at what bubbyway has become, is that software written for specific people against specific constraints has a shape you cannot reverse-engineer from a product aimed at no one in particular. The wishlist that hides its own state, the medicines collapsed by default, the chore rotation that knows there are two of us, the Memories page that surfaces the year quietly behind itself, none of those are the kind of features a roadmap full of personas would have produced. They are the kind of features that come from writing software for the people in the room with you.
I love when a small fix lands because it makes a thing easier for my partner specifically. The fix is usually a couple of lines, sometimes a single line, sometimes just a default flipped or a default kept the same. The cumulative weight of those small fixes is what makes the app feel like the room we actually live in rather than the room someone else thought we should live in, and I find myself caring about that cumulative weight much more than I ever expected to care about a side project that started life as a way to keep track of medicines and chores.
There is a question I am still sitting with about whether this kind of software scales, or whether the act of trying to make it scale is the act of taking away the thing that makes it good. The roadmap towards multi-household deployment is honest, and the work to get there is real, and I do believe other households will benefit from having their own copy of the same shape of app. I also believe that the specific kindnesses of our copy are specific to us, and that the version another household forks and runs will, if they do it right, be specific to them in a way they will not need to explain to me. That is the property I most want the project to keep.