GreenPlate
ABOUT THIS PROJECT
Cook what you already have, and see what it costs the planet.
Most recipe sites assume you are willing to go shopping. GreenPlate starts from the ingredients already in your kitchen and works outward, and it attaches an eco-score to every result so the environmental impact of a meal is visible before you commit to it. A React front end against a Node backend, with accounts and saved favorites.
A typed API on both sides
Express server in TypeScript with recipe endpoints over GET and POST and full CRUD on favorites through GET, POST, PUT and DELETE. Client and server share the same type definitions, so a change to the recipe shape fails at compile time on both ends rather than at runtime in the browser.
Auth, and removing the hardcoded user
Google OAuth through Firebase, an AuthContext holding auth state on the client, and the Admin SDK verifying tokens on the server. The first version had a hardcoded user id standing in for a real account; replacing that with the authenticated user's uid is what turned favorites from a global list into per-user data, and it touched the navbar, the profile page and every favorites route.
Persistence in Firestore
Moved storage into Firestore so accounts and saved recipes survive a server restart, which the in-memory version did not. Favorites are keyed by uid, so the profile page reads only that user's rows rather than filtering a shared collection on the client.
The eco-score itself
Every recipe starts at a neutral 5 and is adjusted from its ingredient list and its nutrition data: ingredient categories move it in steps of 4, 2, 1 and -3 depending on how they are produced, then high fiber pulls it down as a plant-based signal and high saturated fat pushes it up as an animal-product one. The result is clamped to 1 through 10 so no single ingredient can blow out the scale. Recipes come from the Spoonacular API, with the detail requests fanned out through Promise.all rather than awaited in sequence, since the search returns ten at a time.
Where to find it