Inspiration
I save cooking videos from TikTok and Instagram constantly, and I cook almost none of them. They sit in a folder as videos I have to scrub back and forth through just to catch a quantity someone said out loud once. On top of that my family cooks around a dairy allergy, so any recipe we actually want to make needs a translation pass before it is usable in our kitchen. I wanted one place where a link becomes a real recipe, and where that recipe quietly rewrites itself for the person who is going to cook it.
What it does
Miyum turns any recipe into a living cookbook entry.
You paste a TikTok, Instagram or YouTube link, or you photograph a plate of food, and Miyum gives you back a structured recipe with ingredients, steps and timings. From there it adapts. You save a dietary profile once (allergies, sensitivities, dislikes, diet) and one button rewrites the whole recipe around it, swapping butter for olive oil, milk for almond milk, wheat flour for a gluten free blend.
Around that core it handles the rest of the week: a weekly plan, a shopping list grouped by aisle that you can share with someone else, calorie and macro estimates per portion, and a cooking companion that runs timers, keeps cooking alive in the background with a mini player, and asks you at the end to photograph what you made and rate it. There is a discover feed with cuisines and categories, a points and level system, and a mascot that reacts to what you are doing. When you have no idea what to make, a four question wizard picks two candidates for you without spending any AI credit.
Premium unlocks menu mode, where you compose a full multi course menu and cook it as a single flow.
How we built it
It is a pnpm monorepo in TypeScript: a Fastify API, a React Native app on Expo, and a shared package between them.
State lives in Supabase Postgres, and almost every rule lives in the database rather than in the client. Row level security locks each table to its owner, points are written only by database triggers (the authenticated role has no insert or update grant on the stats table at all), and the sensitive dietary table is deliberately kept separate from the public profile table so the discover feed can read one without ever touching the other.
Long jobs go through a Postgres backed queue running inside the same API process, each with an explicit state machine. Importing a link walks queued, fetching, extracting, then ready or failed. Photo to recipe walks a longer ladder: recognising, waiting for you to pick a candidate, generating, auditing, ready.
AI is a provider chain rather than a single vendor. A deterministic mock provider comes first, then Claude, then Gemini, tried in order. Photo recognition uses Gemini vision. The mock is not a test stub, it is a real fallback, so the whole product runs with zero API keys.
Payments run through RevenueCat with a webhook into the API. Builds ship with EAS, push runs on Firebase Cloud Messaging, errors go to Sentry, the site sits behind Cloudflare, and the admin panel is served straight from the API as server rendered pages, so there is no second app and no build step.
Challenges we ran into
Never lie about allergens. When I adapt a recipe for someone with an allergy, the tempting design is to keep retrying until the model returns something clean. I do retry once, with the violation list attached. If the second attempt still contains the allergen, Miyum keeps the first result and returns a visible warning telling you it is still in there. It never fabricates a clean answer. That was the hardest decision to hold, because the honest version looks worse in a demo.
Points were a function of history instead of reality. My first scoring design wrote an event row per action and summed the events. I measured what that allowed: with a single token I could create a thousand recipes and a thousand cook logs, delete all of them, and walk away with fifty thousand points and an empty notebook. I rewrote it so a point event exists if and only if the row that earned it still exists. Deleting takes the points back, unpublishing and unliking are symmetric, and rebuilding from scratch produces the same number.
Two answers to the same question. For a while the subscription record said premium while the quota function said free, because entitlement was being derived in two separate places. Collapsing that into one derivation, with the quota reader as the only source, removed a whole class of bugs I kept rediscovering. A billing failure also does not cut premium instantly any more, because the user has paid and the provider may still be inside its grace period.
Photos are a liability, not an asset. In photo to recipe the uploaded image lives in a private bucket for minutes. The worker deletes it the moment recognition finishes and a sweeper collects anything left behind. Apple's rule for AI generated content built from user photos also needs a real consent gate, so consent is stored on the profile and enforced by the server rather than by the screen.
Credits had to come back on every path. Every failure after the charge point refunds the credit, stamped per loop so a retry cannot refund twice.
Accomplishments that we're proud of
Miyum is live on the App Store with a real subscription and people cooking from it.
What I am proudest of is that a fresh clone runs the entire product with no API keys and no paid service, because the mock provider is deterministic and complete. One script signs up, imports a recipe, saves a dairy allergy profile, adapts the recipe, and then asserts that the butter is genuinely gone and that the credit ledger balances.
I am also proud that the security surface is boring. The database refuses what the client should not be allowed to do, so a compromised client cannot inflate its points, read someone else's allergies, or grant itself premium.
What we learned
With AI features the interesting work is almost never the prompt. It is the state machine around it, the refund on the unhappy path, the retry budget, and deciding what the product says when the model is simply wrong. I now write the failure copy first.
I also learned to push rules down into the database. Every time I moved a rule out of the client and into a policy or a trigger, a whole category of bug disappeared instead of a single instance of it.
What's next for Miyum Social Recipe
Android, then English and more languages inside the app itself. Video analysis, so a recipe can be extracted from the footage rather than from the caption. A weekly plan smart enough to shop from what you already have. And I want to open the cooking companion up so two people in the same house can cook one recipe together from two phones.
Built With
- cloudflare
- eas
- expo.io
- fastify
- firebase
- ios
- postgresql
- react-native
- revenuecat
- sentry
- sharp
- shell
- sql
- supabase
- typescript
Log in or sign up for Devpost to join the conversation.