Thyme is my own recipe manager, and like any good recipe, it’s been through more iterations than I can count since 2020. (Next time, I’ll have to add salt.) It started with a problem at the stove: complicated recipes mean several things cooking at once, each on its own clock, and the timing is usually buried in a sentence halfway down the page. I wanted those timers on screen alongside the recipe itself. Today it’s an Angular front end with TinyMCE editing, on a PHP/MySQL framework of my own.
It started with timers
Thyme reads each step the way it’s written. “Simmer the sauce for 7 to 12 minutes” becomes a timer with a range (7 to 12 minutes) and a label (the sentence it came from). Timers get a panel of their own alongside the step-by-step instructions, so both stay on screen while you cook. The goal is for recipes to be pasted in from anywhere, or written naturally, and still fit neatly into how Thyme works, instead of the other way around.
The same pass also finds every ingredient mentioned in a step, along with its amount, and marks it. Longer names are matched first, so “kosher salt” never gets mistaken for plain “salt”.
A backend that speaks SQL, and English
The backend is my own PHP/MySQL framework. It’s built to pair with a matching Angular service for API calls, so both ends of the app agree on how data moves. It also powers a certification board’s exam platform. At its heart is a set of query classes that build SQL piece by piece. A query reads almost like the sentence you’d say out loud, and any query can print itself as plain MySQL, which makes debugging a lot friendlier.
From the query builder’s own documentation. Joins, grouped and/or conditions, ordering and pagination chain the same way.
Highlights
An ingredient parser that speaks chef
What started with timers turned into ingredient parsing, which has taken most of my attention since. People write ingredients every which way: “2c flour,” “2 cups of flour,” and so on. Thyme turns all of them into structured data with a multi-pass pipeline that normalizes the text and then pulls out amounts, units and ingredients with regular expressions. The approach grew out of the parser I built for NOW Foods’ nutrition tables.
Text Parsing/Regex
PHP
Nutrition up front
Each recipe’s ingredient list goes to an external nutrition API, and the results are saved per serving: calories, protein, carbs, fat, fiber, sugar, sodium and more. Each set of numbers is marked as generated or entered by hand, because external services can be fickle and it’s best to keep local control. The goal is to make that information something you can filter and organize by, not just a table at the bottom of the page.
PHP
Data Architecture
Just the recipe, please
Recipes online tend to come with a life story attached. Thyme keeps the “about” on its own Info tab, separate from the instructions, so nobody has to read through an entire detective novel to find the recipe itself.
UI/UX
Angular
TypeScript
Cooking for a crowd, or just for two
Every recipe knows how many servings it was written for. Change the number, and every ingredient amount scales to match, so the shopping list is right for however many people you’re feeding.
Angular
UI/UX
TypeScript
Sharing the kitchen
Role-based access control with roles, groups and fine-grained permissions, so several people can collaborate on a recipe collection.
Data Architecture
PHP
What’s next
More timer work. Timers came first and still have the most room to grow.
Personal notes. Notes that stay with a recipe for one cook: “double the sauce,” “might be too spicy for Kevin.”
Variations. Swaps that are part of the recipe itself: “use gluten-free flour in place of all-purpose.”
Looking back
I set out to build a timer and ended up building a recipe parser, a nutrition tracker and a PHP framework to hold it all up. On a client project that’s scope creep. On my own time it’s the whole point: Thyme is where I get to follow a problem as far as it goes, and it hasn’t run out of road yet.