Why I built it
Most recipe sites make you scroll past a long blog post, pictures, and the author’s life story before you reach the recipe, and then an ad pops up in the way. I hated that. So in March 2021 I started my own: an ad-free site that works as my personal cookbook for the recipes I’ve made.
That reason still holds, but it isn’t the main one anymore. Mostly I want an accessible place to keep my recipes, and an easy way to share them with coworkers, friends, and family.
How it works
Scott’s Cookbook is a static site built with Gatsby 5, React, TypeScript, and Material UI. It holds over 70 recipes, and the count keeps growing. Each one is a single Markdown file, and all of its data lives in the YAML frontmatter: title, topic, rating, times, a list of ingredient objects, and ordered directions.
Gatsby parses those files, turns the frontmatter into fields in its GraphQL data layer, and builds one page per recipe from a single template, using the filename as the URL. AWS Amplify watches certain branches of the repo and rebuilds and redeploys the site when it detects a change.
On the page
- Search, filter, and sort. Search matches the title, topic, ingredients, and directions by substring rather than fuzzy matching, and title matches always rank above ingredient or direction matches. The list filters by topic, one of nine, and sorts by rating by default.
- Cooking mode. Keeps the screen awake while you cook. It requests a Screen Wake Lock, falls back to NoSleep.js (a tiny hidden looping video) on browsers without one, and takes the lock back when you return to the tab.
- Shopping mode. Adds a cart link to each ingredient that searches Amazon Fresh, Instacart, Walmart, or Whole Foods. A cookie remembers whether it’s on and which store you picked.
- Bean converter. Converts between dried, canned, and cooked amounts for six kinds of beans, in metric or imperial. A small Python script generated its conversion table from dry and cooked weights and volumes.
Keeping recipes from disappearing
A YAML mistake used to be invisible. One missing comma inside an ingredient entry made the whole recipe fail to parse, and it silently dropped off the site. By the time I fixed it, seven recipes had vanished that way.
Now one shared validator checks every recipe in three places: a CLI script, a Jest test over the whole collection, and a hook that runs before Gatsby starts and fails the build with a readable report. An add-recipe skill for Claude Code sends AI-written recipes through the same checks. Playwright tests cover the home page, recipe pages, the tools page, and navigation.
The hard part
Early on, the hard part was GraphQL. Every page in a Gatsby site gets its data by querying that layer, and back then every change was a lot of manual work.
The more interesting wrong turn was nutrition. I wanted the site to track calories and macronutrients, so I built a recipe creator. I started in 2021 with a local USDA raw-foods nutrition CSV, and in 2022 I switched to searching USDA’s FoodData Central API, limited to its Survey (FNDDS) dataset. Users pasted in their own API key.
The math was straightforward. USDA reports nutrients per 100 grams. Each ingredient was converted to grams through a portion the user picked, like a cup with its gram weight, and then every nutrient was scaled by grams over 100 and summed across the recipe. The code even refused to add two readings of the same nutrient reported in different units.
I went in assuming a food like an egg or celery has one nutritional readout. It doesn’t. The numbers differ by manufacturer, by season, and by a lot of other factors, and different sources report different readouts for the same food.
The problem was never the arithmetic. It was the inputs.
I eventually decided against tracking nutrition on the site, and I removed the recipe creator in November 2025.
What I learned
I learned a bit of GraphQL, and I’d still pick Gatsby and GraphQL for a site like this, one that keeps growing. Hosting has gotten easier too. My older sites meant configuring S3 buckets and Route 53 settings by hand. This one runs on Amplify with CloudFront in front, and the hosting is cheap.
How I work on the site has changed more than the stack. I now update it with agentic coding tools as an expert coding partner, which makes it a lot easier than the manual work of the early years. If I started over, I’d go agent-first from day one: write a specification with GitHub Spec Kit, name the technologies and frameworks I want in it, and let that keep the work clean for agents while still leaving room for me to build features.
Outside the code, the nutrition numbers were the interesting part: what each measurement meant, and why different sources disagree.
A nutrition label looks like a measurement. For a lot of foods, it’s a best estimate.
What’s next
I consider the site feature-complete. What’s next is adding more recipes as I go along. If the collection gets big enough that finding things gets hard, I’ll look at better filtering then. The nutrition tool could probably come back, but for now the plan is just recipes.


