Damián Vidal

← Projects

Forkcast

Weekly meal planner, recipe box, and virtual pantry. The shopping list writes itself.

Stack: Nuxt 4, Vue 3, TypeScript, Neon Postgres, Drizzle, Better Auth, Vercel Blob, Gemini, PWA

Why

I cook for one, and I plan every Sunday: what I’m eating for lunch and dinner all week, then one grocery run. For a long time that plan lived in scattered chats and PDFs. Recipes were TikTok links I’d never find again, the shopping list was rebuilt from scratch every week, and I kept buying things I already had at home.

Meal-planning apps exist, but they’re built around their own recipe catalogs and assume a family of four. I wanted my own dishes, my own pantry, and a list that only contains what I’m actually missing.

So I built it for myself, and I use it every day. Built so other people can use it too, without me having to rewrite it.

What it does

Forkcast landing page: weekly menu, pantry, shopping list

How it works

Nuxt 4 (Vue 3, strict TypeScript) on Vercel, Neon Postgres via Drizzle, Better Auth with a 6-digit email code sent by Resend. Not a magic link, because on an iOS PWA the link opens Safari instead of the app. Photos go to private Vercel Blob storage, never public URLs.

Every pantry change is logged as a movement (bought, cooked, adjusted, expired) in the same transaction that updates the stock, so the stock always equals the sum of its history. Cooking a meal is idempotent and reversible, and that history is what lets the app learn real consumption.

All business rules (shopping list, leftovers, weekly limits, slot suggestions) are pure functions with unit tests. Repositories are tested against an in-memory Postgres (PGlite) running the real migrations, and Playwright runs at 375 px. Multi-user from day one: every query is scoped by user_id, and nothing personal is hardcoded.

Status

In daily personal use since late September 2026. Live on its own domain in private beta: sign-ups are closed and new emails join a waitlist. Spanish UI for now, with all copy centralized for i18n. I’m keeping the public launch on hold while I use it daily and iron things out.

See it