Research automation, data design, frontend, maintenance pipeline
Team
Solo
Tools
Research agents, JavaScript, Algolia, Playwright, Anthropic API, GitHub Actions
Interactive sketch
Bananain 67 smoothies
The menu kept disappearing
When friends visit LA for the first time, I take them to Erewhon. It feels like the LA tourist thing to do. At some point I tried to look up old smoothies I had ordered with them, and the pages were just gone. Erewhon rotates limited smoothies out of its menu, and the old pages usually disappear with them.
The history was still scattered across press coverage, archived menus, partner recipes, and copycat posts. I set out to rebuild the full catalog from those public sources. The dated records reach back to 2021, and the older house staples are in there too, grouped as undated, since there is not enough surviving evidence to pin them to a launch month.
The main archive page on the live site.
Rebuilding it with research agents
The task was open-ended internet research. For every smoothie I needed proof it existed, its dates, its collaborator, and its ingredient list. I ran it with Claude subagents that swept press stories, Wayback Machine snapshots, brand recipe pages, and recipe transcriptions, then I synthesized their findings into records.
It burnt millions of tokens because the research was open ended and each subagent worked in its own context. I was on a subscription plan, so the cost was fine. The result was over 100 smoothie records backed by more than 250 source links, with each record keeping its sources attached. The oldest drinks were the hardest, since some only survive in an Instagram post or an article that lists half the ingredients.
A finished record with its source links at the bottom of the sheet.
The ingredients page
The archive is a chronological catalog with filters for celebrity collabs, brand collabs, and house drinks, and each smoothie opens into its own sheet. Erewhon publishes full ingredient lists and markets these as health drinks, so I added an ingredients page that indexes every one and counts how often it appears. Banana leads at about 70 smoothies.
The visual style took the most iteration. Every ingredient is a flat-color SVG icon with an ink outline. I generated the icons with Claude and reworked the ones that missed. On top of that, the whole page runs a constant wobble where the linework redraws a few times a second, inspired by skribbl.io, a game I grew up playing. The wobble is what makes everything look hand drawn. There are over 170 icons covering more than 200 ingredients, since close variants of an ingredient share an icon.
The ingredients page on the live site.
Automating menu updates
The deep research only had to happen once, to recover the past. From here on, any smoothie Erewhon releases will show up on their own site when it launches, so keeping the archive current is a much smaller problem than building it was. The scheduled refresh reads the live menu feed instead of repeating the historical search. I built a pipeline that checks the live menu on a schedule, and it ended up being my favorite part of the project.
The menu page itself is an empty shell that loads its products from an Algolia search index, so the pipeline reads the same public feed the browser uses. Each drink it finds gets sorted into skip, still live, relaunch, rename, or new. Erewhon sometimes reuses a product listing for a different edition, so the archive trusts its own slugs over their product IDs. Drinks that fall off the menu are marked discontinued, and nothing gets deleted from the archive.
Guardrails
A bad automated run could wreck the archive, so the pipeline refuses to ship anything suspicious. It stops if too few smoothies come back, if any of them arrive missing an ID or a name, if too many look new at once, or if one pass would discontinue more than half the drinks it still counts as live. Those patterns usually mean the fetch broke or the site changed, so the pipeline waits for me to look at it.
The expensive steps run last. A headless browser only opens the handful of genuinely new product pages, and a model only sees ingredient text the regex matcher could not handle.
Every update is a pull request
GitHub Actions runs the refresh on the 1st and 15th. If nothing changed, it stays quiet. If something did, it opens a pull request with the images, ingredients, and status changes filled in, and I decide whether it merges.
The first automated refresh added Tree-Ripe Mango Protein Trifle with 11 ingredients. Ten matched the existing icon set. Granola was the only new one, added with a placeholder icon for me to replace.
The automated pull request that added Tree-Ripe Mango Protein Trifle and proposed granola as a new ingredient in the archive.