Inspiration I kept buying ingredients for specific recipes, only to watch them rot in my fridge. Cilantro for tacos. Buttermilk for pancakes. Fish sauce for Thai curry. Every time, I'd use 10% of the ingredient and throw away 90%.

Recipe apps are backwards. They start with a recipe and ask you to buy things. Nobody starts with what you ALREADY have.

I wanted to solve food waste at the source - by helping people cook with what's already in their kitchen. PantryPanther turns your existing ingredients into meals instead of sending them to the trash.

What it does PantryPanther is a smart recipe finder that shows you meals you can make with ingredients you already own.

How it works:

User types ingredients they have (autocomplete suggests from 1,000+ real recipes)

App scans the recipe database and calculates a match percentage for each recipe

Recipes are sorted by highest match percentage (the ones you can almost make appear first)

Users can filter by recipe name, max cook time, or minimum rating

Click any recipe to open full instructions on the original source

Save favorite recipes - they persist across sessions with no account needed

Example: Add "chicken, rice, onions, garlic" → PantryPanther shows chicken stir-fry (100% match), chicken soup (75% match, missing carrots), then other options.

All data stays in your browser. No accounts. No tracking. Just cooking.

How we built it Frontend Framework: React with functional components and hooks (useState, useEffect, useContext)

Build Tool: Vite - provided instant hot module replacement and fast production builds

Data Processing: PapaParse - parsed 1.6MB CSV file into JavaScript objects client-side

Data Source: Kaggle's "Better Recipes for a Better Life" dataset - 1,090 real recipes with ingredients, prep times, cook times, ratings, and URLs

Hosting & Deployment: Vercel - one-command deployment with free SSL and global CDN

Persistence: Browser localStorage - saves pantry ingredients and saved recipes without backend infrastructure

Key Algorithms:

Ingredient cleaning function strips measurements (cups, tbsp, lbs) and filler words (chopped, minced, fresh)

Match scoring calculates percentage of pantry ingredients found in each recipe

Real-time filtering applies search terms, time limits, and rating minimums

Challenges we ran into

  1. Parsing messy ingredient strings

The CSV ingredients field looked like: "3 tablespoons butter, 2 pounds Granny Smith apples, peeled, ½ cup sugar"

Extracting clean ingredient names required removing quantities, units, preparation words (peeled, chopped, minced), and splitting by commas while respecting parentheses. The cleaning function took 3 complete rewrites.

Solution: Built a multi-step cleaning pipeline: split → remove numbers/units → remove filler words → lowercase → trim.

  1. Ingredient matching accuracy

Substring matching meant "chicken" matched "chicken breast" and "chicken broth" - good. But "salt" matched "garlic salt" - not ideal.

Trade-off: Chose substring matching for speed over fuzzy matching (Levenshtein distance) which would be slower with 1,090 recipes × pantry size.

  1. CSV loading performance

Fetching and parsing 1.6MB of CSV data caused a 1-2 second delay on first load.

Solution: Added loading spinner, parse once and keep in memory, subsequent interactions are instant. For v2, will pre-process CSV into JSON at build time.

  1. localStorage sync across components

Pantry ingredients needed to update RecipeList in real-time while saving to localStorage.

Solution: Lifted state to App.jsx, passed down setters as props, saved to localStorage in useEffect whenever state changed.

Accomplishments that we're proud of Smart matching algorithm that ranks 1,090 recipes in real-time as users type ingredients. The app feels instant despite processing thousands of data points.

Complete offline-capable architecture - No backend, no database, no accounts. Everything runs in the browser and persists to localStorage. Users own their data.

Extracted 2,815 unique ingredients from messy CSV strings. The autocomplete dropdown suggests only ingredients that actually exist in the recipe database.

Built a feature users actually love - Saved recipes, match percentage bars, and ingredient autocomplete get positive feedback. Users don't request login features.

Solved a real personal problem - I now use PantryPanther weekly. My food waste is down significantly. Knowing something I built helps me (and others) is the best accomplishment.

What we learned Technical lessons:

Start with data structure - Changing ingredient schema halfway through is painful. Plan parsing logic before writing UI.

localStorage is underrated - Users love "no account required." For tools like recipe finders, it's a feature, not a limitation.

Vite > Create React App - Hot reload is milliseconds vs seconds. Builds are smaller. Developer experience is dramatically better.

CSV parsing on client is viable - For datasets under 5MB, fetch and parse once. Users wait 1-2 seconds then everything is instant.

Browser caching is aggressive - Favicons, service workers, and asset caching require explicit invalidation strategies.

Product lessons:

Watch real usage - Thought collapsible filters were important. Users just want them always open. Match percentage bars get more attention than rating stars.

Solve your own problem first - Building something you actually use ensures quality. I'm my own harshest critic and most loyal user.

What I'd do differently:

Pre-process CSV to JSON at build time (faster first load)

Add fuzzy matching for ingredients (better accuracy)

Implement barcode scanning (faster ingredient entry)

Write tests (refactoring ingredient parser was nerve-wracking without tests)

Built With: React, Vite, PapaParse, Vercel, Kaggle Dataset, CSS3, localStorage API

Built With

Share this project:

Updates