·4 min read

How I Redesigned a Meal Planning App UX: From Panel to Modern Food-First Design

build-in-publicux-redesigndesign-systemnextjsshadcn-uimeal-planning-app|
PostLinkedIn

Melio is an AI-powered meal planning app. It generates personalized nutrition plans, manages dietary profiles, builds shopping lists. Functionally it worked — but visually it looked like a back-office admin panel. Data tables, utilitarian headers, developer-facing layouts. Not the kind of interface you want open on your kitchen counter.

I decided to redesign the entire app UX using a research-driven approach. Here's how I did it across 47 routes without breaking a single feature.

Why Research-Driven UX Design Matters

Redesigning a product based on gut feeling leads to inconsistent results. Instead, I started with structured UX research before writing any code.

I studied competitor meal planning apps — Mealime, Eat This Much, and Whisk — to identify what design patterns work for food products. I documented findings with screenshots and stored everything in a research folder that became the foundation for every design decision.

Key patterns I found across successful food and wellness apps:

  • Meals displayed as visual cards with food photography, not table rows
  • Today's plan as the primary landing surface — users open the app to see what to eat now, not to navigate a dashboard
  • Macro nutrition data shown as compact visual tiles (rings, bars, progress indicators) rather than spreadsheet columns
  • Progressive disclosure — hide complexity until the user explicitly needs it
I also applied Nielsen's usability heuristics systematically: visibility of system status during plan generation, recognition over recall through visual card layouts, consistency via a unified design token system, and aesthetic-minimalist design by removing every element that doesn't serve the user's immediate goal.

This research phase produced a master plan document with per-screen specs for all 47 routes.

How to Structure a Large-Scale App Redesign: The 9-Wave Approach

Redesigning a full-stack app with dozens of routes needs a deliberate sequence. I organized the work into 9 waves, each building on the previous — a method that keeps the codebase stable at every step.

Wave 1: Design Tokens and Color System

New design tokens set the visual direction — warm cream backgrounds (--background), deeper sage as the primary color, coral reserved exclusively for recommended actions. Border radius set to 1rem for a softer, modern feel. Because every component reads from HSL CSS variables, this single change cascaded through the entire app automatically.

Wave 2: Reusable UI Component Library

I built 13 reusable UI primitives using shadcn/ui: MealCard for visual meal display, MacroTile and MacroRing for nutrition data visualization, DayTabStrip for plan navigation, EntityCard for library items, AIChatFAB for the AI chat assistant, and more. All follow compound-component patterns so the React Native mobile app (Tamagui) can reuse the logic later.

Wave 3: App Shell and Navigation Redesign

The neon green header band became a minimal transparent 48px bar. Sidebar navigation consolidated from scattered links into 3 logical groups. This follows the UX principle of reducing navigation cognitive load — users shouldn't spend mental effort figuring out where things are.

Waves 4–5: Dashboard and Meal Plan Views

The dashboard shifted from a generic feature overview to a "Today's Meals" hero layout with an UpNext rail and library stats. This mirrors how Spotify surfaces "Made for You" content — lead with what's relevant right now.

Generated meal plans moved from a flat list to a card grid with thumbnail montages and a sticky DayTabStrip. This follows the card-based browsing pattern used by Pinterest, Airbnb, and most modern content-driven apps.

Wave 6: Onboarding Wizard Simplification

The meal plan wizard was reduced from 4 steps to 3 with a dot progress indicator. Research showed the original flow had unnecessary friction — a step that could be inferred from previous answers, and a development-mode guard that blocked access in production. Following the 3-click onboarding principle, I eliminated every unnecessary interaction.

Wave 7: CRUD Screens — From Data Tables to Card Layouts

People, Nutrition Profiles, Meal Plans, Saved Recipes, Shopping Lists — all migrated from MUI data tables to EntityCard + SectionGroup layouts. Data tables are designed for admin users. Card layouts are designed for consumers. Same data, completely different experience. This is the single change that most transforms how the app feels.

Wave 8: SaaS Pricing Page Design

Billing adopted a 3-tier pricing layout with the Pro tier visually emphasized using a coral badge and slightly larger card. This is a standard SaaS pricing pattern backed by the decoy effect in pricing psychology — the middle option appears most valuable when framed between a basic and premium tier.

Wave 9: Settings Consolidation

Scattered profile pages consolidated into a single /settings route with 4 clear sections: Account, Preferences, Active Plan, and Danger Zone. One URL, one mental model.

UX Standards and Accessibility

Throughout the redesign, I held to industry standards on every route:

WCAG AA accessibility — 44×44px minimum touch targets on all interactive elements, visible focus rings for keyboard navigation, and sufficient color contrast ratios across both light and dark themes. Mobile-first responsive design — every component works at 375px viewport width. The shell adapts to a bottom tab bar on mobile, following iOS and Android platform conventions. Internationalization (i18n) — every new user-facing string routed through t() translation keys in public/locales/en/*.json. Zero hardcoded text. Design system consistency — shadcn/ui components and Lucide icons exclusively. The HSL token contract stayed structurally identical; only values changed. This means zero breaking changes for any consuming package. Form architecture preserved — Server Actions + useActionState + Zod validation on every form. The paywall contract (useTierLimits(), , ) remained untouched. Visual redesign should never break business logic.

Results

145 files changed across the web-agent package. TypeScript type checker passes clean. Linter shows 2 minor warnings. Production build succeeds.

The app went from feeling like an internal tool to looking like a modern meal planning product. That transformation came from systematic research and established UX principles — studying what works in the industry and applying it methodically, wave by wave.

Oleksandr Yusypenko

Oleksandr Yusypenko

Senior Full-Stack + AI Engineer. Building in public — AI agents, LangGraph, production systems.