Get in touch

From the workshop

The Saucery

Family meal planner that thinks ahead.

Paste any recipe (a link, a screenshot, even a photo of a cookbook page) and it lands as a clean, structured recipe. Meal plans and shopping lists the whole family shares, priced against the supermarket you actually walk into. Native iOS and Android on a Laravel backend.

In beta Web iOS Android
Laravel SwiftUI Kotlin Recipe import Agentic assistant Grocery pricing
The build story

The build story

Dinner, debugged.

Every family runs the same nightly standup: what’s for dinner? Meal planning is really a coordination problem: recipes live in screenshots and saved links, the shopping list lives in someone’s head, and the plan lives nowhere. The Saucery is my second run at solving it. The first attempt was Flutter; it taught me what the product needed to be, and then I shelved it. This version is a clean Laravel API with two fully native clients (SwiftUI on iOS, Jetpack Compose on Android) because a kitchen app lives or dies on feeling fast in one hand while the other one stirs.

Paste literally anything

The make-or-break feature is recipe import: if adding a recipe is harder than screenshotting it, nobody migrates. So the importer refuses to depend on websites being well-behaved. It works through a chain of fallbacks until something gives up a recipe:

URL  →  structured data (schema.org)   → done
     →  stripped HTML → Claude          → done
     →  video description → Claude      → done
     →  photo of a cookbook page → OCR
        → Claude vision                  → done

A magazine page, a TikTok link, grandma’s handwriting: the pipeline doesn’t care about markup, only about ending with ingredients and steps. Imports run on a stronger model than chat, because extraction is where accuracy pays for itself.

An assistant with its hands on the tools

Whisp is the in-app assistant, and it’s agentic rather than chatty: nineteen registered tools covering recipe search, the meal plan, the shopping list, cooking history, pantry estimation, the help centre, even grocery price lookups. Ask “plan three dinners the kids will actually eat and put the missing bits on the list” and it operates the same API the apps use. The economics are engineered, not hoped for: a fast model for conversation, prompt caching on by default, fixed credit costs per action, per-family daily limits, and every AI call logged with token pricing attached, so the free tier can’t quietly become a fire.

The week, priced at the shop you actually walk into

A meal plan that can’t tell you what it costs is half a product. So the shopping list prices itself against a real supermarket: Woolworths, Pak’nSave or New World, and then the specific store, because the last two set prices branch by branch and a New World in one suburb can be dearer than the one two suburbs over. The interesting part is the honesty. The app keeps its own price history, so when something is flagged as a deal it can say whether it is one, or whether that is just what the thing costs. Pak’nSave doesn’t publish a was-price at all, so instead of inventing a saving it shows the multibuys and says why. New Zealand only, for now.

One source of truth, synced live

Everything is family-scoped on the server (recipes, plans, staples, the list) with roles and invite codes, and the clients are deliberately thin. WebSockets push every change, so when one person ticks off the tomatoes in aisle four, they vanish from the other phone in aisle seven. The backend carries over 1,200 tests, which is what lets two app stores’ worth of releases ship weekly without fear.

Entitlement is a question, not a column

A paid tier that sells on the web, in the App Store and on Google Play has three sources of truth for one yes-or-no question, and they disagree. The rule the whole billing layer is built on is that access is never stored: no webhook is allowed to set a flag, it writes down what the store said, and the next read works the answer out again from the rails in a fixed order. A verifier that can’t reach its store returns a 503 rather than an opinion.

The sharpest lesson came from Stripe. One Stripe account sits behind about eight of my products, and a webhook endpoint is not scoped to the app that created it: every endpoint on the account receives every event of the types it subscribes to, from every product. There is no setting to change that, which I established by checking both of Stripe’s APIs rather than by assuming. So every checkout here stamps the session and the subscription with which app it belongs to, and a guard drops anything this database doesn’t recognise and answers 200 while it does it. A non-2xx would make Stripe retry a deliberate drop for ever.

The brand went round twice

The first brand argued with itself for a year. The Flutter prototype wore a flat cartoon chef on a loud orange tile: fine for a placeholder, wrong for a thing that wants to feel like a well-loved recipe notebook. So the rebuild went hand-painted: watercolour everything, a warm terracotta-and-sage palette over cream. For a while the app icon was the chef character, and I even shipped a release that zoomed right in on her face. Then I shrank it to home-screen size and watched it turn to mush: a face dates, fights the icons either side of it, and quietly whispers “chatbot”.

What followed was a pile of dead ends. Toques flat and painted, a whisk, a monogram “S”, sprigs, leaf after leaf. I even wrote a little script to generate a parametric SVG leaf with proper depth before admitting the hand-painted one I’d been sketching was better. The lesson underneath all of it: the mascot and the logo are two different jobs. So the mark became a single watercolour basil leaf, the chef stayed inside the app as the companion, and a brush-script wordmark tied the two together.

It was good work, and in August 2026 all of it went in the bin. “SousChef” was a description of a job rather than a name, and it put the second-in-command in the title of a product meant to run the kitchen. The App Store listing was the tell: it had to go up as “SousCheffe”, which is not a word and not a thing anybody would search for. The app is now The Saucery, which does three jobs in one word. A saucery is the room in an old house where the sauces were made. Sorcery is what a good kitchen looks like from outside it. And a source is where a recipe comes from, which is the feature the whole thing is built on.

Started here The original flat cartoon-chef app icon on an orange tile.
Flat chef · the placeholder
↓ the roads not taken ↓
Icon concept explored and dropped: Chef as icon.
Chef as icon
Icon concept explored and dropped: Toque.
Toque
Icon concept explored and dropped: Whisk.
Whisk
Icon concept explored and dropped: Monogram.
Monogram
Icon concept explored and dropped: Leaf, outlined.
Leaf, outlined
Icon concept explored and dropped: Leaf, painted.
Leaf, painted
↓ landed here, for ten weeks ↓
The hand-painted watercolour basil-leaf app icon that shipped as SousChef.
The basil leaf · June 2026
The retired SousChef wordmark: a watercolour basil leaf above a brush-script “SousChef”.
…and its wordmark
↓ then the name went ↓
The Saucery app icon: a swash letter S drawn in two greens on parchment.
The swash S · today
The Saucery wordmark: an engraved capital S with a long swash, set against the words “The Saucery”.
…and its wordmark

The new direction is Victorian copperplate: cross-hatched engraving, forest ink on parchment, every fixed illustration cut as line work rather than painted. Three directions were written out in prose before anybody drew anything, which is the cheapest place to find out an idea is thin. Gini drew the wordmark and the icon, and the palette came out of her files rather than out of a picker, so for the first time the brand wasn’t mine to argue with.

Even the icon had to give something up. The full mark is an oval, a swash S and an open book, and at 1024 pixels it is a lovely thing. At the 60 pixels a phone actually draws, the book closed into a smudge and the oval into a ring. Dropping both bought the letter more than twice the height, so the app icon is the S standing on its own, and the emblem keeps the jobs it was drawn for. The S is rationed everywhere else: it is allowed in exactly three places, and a section divides with a double hairline rule rather than a flourish.

One of those three places

The home page is a saucepan, and the ribbon of steam coming off it loops once into the swash S of the wordmark. It is one engraving, cut in two at the last row above the rim so the halves recomposite exactly, and that drawing is what you get with no JavaScript. When the canvas can run, the drawn ribbon steps aside for ink that travels: a few hundred dots following the ribbon’s own centreline, traced off the plate by a script rather than redrawn, so the S the steam makes is the S in the wordmark and not a near miss. It thins as it climbs, because that is what steam does. Run a cursor through it and it parts.

An engraved saucepan, its steam curling once into the Saucery’s swash S.
The Saucery’s own home page, running here

The mascot that isn’t one

The assistant went the same way as the leaf. It used to be Sous, a chef with a backstory and a face, and a face is a promise a piece of software can’t keep: it invites people to talk to a character instead of using a tool, and it dates faster than anything else on the screen. Whisp replaced it. Whisp is a wisp of steam, which is to say it is the same S again. No face, no body, no backstory, never a mascot. It has simply been in every kitchen. It answers on ruled note paper, one thought to a note, and it never opens by announcing what it is, because nobody needs telling.

The household is the QA team

The Saucery has been in real daily use through beta, and the commit history shows it: fixes traced to numbered tickets filed from the apps by the people who actually cook with it. A report goes in from the screen it happened on, with the offending bit of the page dragged out as a screenshot, and lands in the same queue the work is scheduled from. The loop from “this annoyed me at dinner” to “fixed in the next build” is short enough that the family keeps filing.

Got a product that needs a backend, two native apps, and AI that pays its way? Here’s how we could work together.

Visit The Saucery