AI Designer
Something from nothing. How I built an app that turns fridge leftovers into a recipe
You type what's left in the fridge — you get a recipe matched to your equipment, diet, and time. Not a prototype: a complete product with frontend, serverless layer, prompt engineering, and a custom design system, built from scratch.

Most people throw out food not because they can’t cook. They throw it out because they don’t know what to cook with it. Three ingredients that don’t seem to go together end up in the trash — along with the money. WTFridge solves exactly this problem: you type what you have at home, and the app generates a recipe matched to your equipment, diet, time, and hunger level.
This isn’t another demo with a single text field. It’s a complete product I designed and built from scratch — from concept and UX, through a custom design system, to the server layer and prompt engineering. I’m showing it here because it best answers the question I hear most often: “OK, but can you deliver it to the end?”
What it actually is
A web app where you enter a list of ingredients and a few preferences, and in seconds get a concrete recipe: name, ingredient list highlighting what you already have, steps, macros, shopping list, and a hint on what to use first. No registration, no installation, in two languages.

The app’s heart: dynamic prompt builder
All the value sits where the user can’t see it. The backend is one serverless function (Netlify Functions) acting as a secure proxy to the language model — the API key never reaches the browser. Its most important part is the dynamic prompt builder, which assembles a precise model instruction from twelve input variables:
- hard dietary restrictions (keto, veggie, low FODMAP, allergies),
- available equipment (oven, air fryer, thermomix…),
- shopping mode (zero shopping vs. max three items),
- nutritional goal (more protein, fewer carbs, comfort food…),
- time limit, difficulty level, number of servings, flavor preferences.
The model always returns structured JSON with a strict schema, and every response is validated against a TypeScript-defined interface. If something doesn’t match the schema — the user doesn’t see a broken screen, just a clear message. This is the same discipline I know from prepress: the file is either correct, or it doesn’t go on the machine.
Custom design system, not a UI kit
Instead of reaching for a ready-made component library, I built my own system in Tailwind: five custom color palettes, warm shadows, custom entry animations, typography based on Instrument Serif and Inter, a consistent eight-pixel rhythm, and soft rounded corners. Zero UI dependencies — apart from icons, nothing is borrowed. This gives the app character instead of looking like every other project on the same boilerplate.
The generator form has six independent sections with different interaction types — chip input with keyboard shortcuts, multi-toggle equipment, binary “desperation level” choice, dietary profiles with a field for custom exclusions. The whole thing is designed to guide a novice, not intimidate them with the number of options.
Deliberate decisions
A good product is as much about what you don’t add. A few decisions backed by concrete reasoning:
- No database. Saved recipes are stored locally in the browser. At this scale, it’s the right call: no accounts, no personal data to manage, zero infrastructure. The app works offline.
- Custom i18n system instead of a heavy library — over 120 translation keys in PL and EN, with correct pluralization, language auto-detected. Two languages don’t need a framework with ten dependencies.
- OpenRouter instead of coupling to one provider — changing models means changing one environment variable. I’m not locked into a single API.
- Full error and timeout handling — I distinguish between missing key, model error, timeout, and empty response. Each case has its own clear message.
Why this is in the portfolio
WTFridge is roughly 2,500 lines of TypeScript, twelve prompt control variables, two languages, and zero UI dependencies. But the numbers are secondary here. What matters most is what this project proves: I can walk the entire path independently — from spotting a real problem, through designing the interface and visual system, to writing working code and shipping a product that just works. A designer who understands how the thing they’re designing is built makes better decisions along the way.