Dish Today
Meal planning, listing & sharing app
Challenge: Browser storage limits for large planner state
Next.js, TypeScript, Prisma, PostgreSQL, Tailwind CSS

Short walkthrough of the weekly planner, grocery list generation, and ingredient marketplace.
Most meal planning apps become slow or fragile when users build up large amounts of data such as recipes, images, and weekly plans. I wanted to create a planner that stays responsive, works smoothly in the browser, and remains usable even under storage constraints.
I built Dish Today to keep daily interactions fast while supporting social features:
- Personal recipe library with public and private recipes
- Drag-and-drop weekly meal planner
- Grocery list generation
- Ingredient-based recipe suggestions
- Community ingredient market with map support
Hybrid persistence for quota-safe local-first planning
The hardest part of this project was storing complex user-generated planner data reliably in the browser. Weekly boards, recipes, and images can grow quickly, which makes browser storage quotas a real constraint.
I solved this with a hybrid persistence system:
- localStorage for fast access
- IndexedDB fallback for larger payloads
- Metadata markers to coordinate storage targets
- Quota recovery through image recompression and cleanup
- Generation-based saves so async recovery cannot overwrite newer state
The architecture separates highly interactive planner state from shared social data to preserve responsiveness and keep collaboration features scalable.
Client
Next.js App Router UI with interactive planner state and local persistence.
Server
Prisma + PostgreSQL for accounts, published recipes, follows, and market listings.
Data strategy
Planner state is local-first while shared and social data is stored on the server.
Key Engineering Decisions
Offline-first planner
Prioritized speed and responsiveness for planning sessions, with a more complex local persistence layer.
Client/server responsibility split
Kept heavy interactive state close to the UI while centralizing shared data, reducing server chatter during planning.
Graceful degradation under storage pressure
Preserved data integrity and continuity at the cost of extra recovery logic and state versioning.
Current Limitations
- Planner state is primarily device-local, not fully cloud-synced.
- Browser storage limits still constrain rich media.
- Local-first design adds persistence complexity.
Planned Improvements
- Add multi-device sync.
- Move image storage to object storage/CDN.
- Improve ingredient matching.
- Add conflict resolution for sync.