Every blend you save from the Mixer (or import from a CSV / paste) lands here. The list view supports search, filter, sort, and bulk actions. The edit view re-loads a recipe back into the Mixer for tweaks. The public share link surfaces a read-only recipe at a short URL you can DM, post, or print.
Browse + filter
- 1
Open Recipes
Sidebar →
Recipes(URL:/recipes). - 2
Filter the list
- All / Starred — your favorites first.
- Family — bourbon, floral, gourmand, etc.
- Wax — only recipes built on a specific wax.
- 3
Sort
Newest / Oldest / A–Z / Most Made (count of
batch_logentries). - 4
Star favorites
Click the ☆ on any card. Filter by Starred to surface them.
Edit a recipe
- 1
Click any card
Routes to
/recipes/[id]which loads the recipe back into the Mixer scratchpad withisEditingset true. - 2
Adjust whatever
Sliders, oils, name, description, wax — same controls as a fresh blend.
- 3
Save
UPDATE BLENDoverwrites the existing recipe.SAVE AS VARIANTcreates a new recipe with a (variant) suffix and leaves the parent untouched.
recipe_history. You can roll back via the History panel — see “History + restore” below.Import from CSV
For migrating recipes from spreadsheets, your old POS, or another platform.
recipes-template.csv
Headers + 5 AI-generated example recipes. Pre-formatted to drop into the importer.
- 1
Open the importer
From Recipes list → top-right
IMPORTbutton. - 2
Upload OR paste
Either drop a CSV file onto the dropzone, or paste comma-separated rows directly into the textarea. Both accept the same format.
- 3
Format expected
Header row required. Columns:
name, description, wax, fragrance_load_pct, oil_1, pct_1, oil_2, pct_2, ... Library at Dusk, "Old leather chairs, cracked spines, low oil-lamp glow", Coconut Apricot CAW464, 8, Tobacco Leaf, 35, Old Books, 25, Sandalwood, 25, Amber, 15
name+ at least oneoil_N/pct_Npair are required. Everything else is optional.- Up to 10 oil/pct pairs per row.
- Quoted strings can contain commas — useful for description.
- Percentages must sum to 100. Off-totals get flagged in the preview but you can override.
- Lines starting with
#are ignored as comments.
- 4
Review the match preview
The importer fuzzy-matches each oil name against your library + the catalog using Jaccard scoring with name-match-always-wins. You'll see one of:
- EXACT — confident match, ready to import.
- FUZZY — confidence below 0.85; review the candidate before confirming.
- NO MATCH — couldn't find a candidate. You can search manually OR skip this oil.
- 5
Resolve no-matches
For any NO MATCH row, click the row to open a debounced catalog search. Pick the right oil, or click
Skip oilto drop it from this recipe (the rest of the recipe still imports). You can alsoSkip recipeentirely. - 6
Confirm import
Click
IMPORT N RECIPESat the bottom. Recipes land + ingredients write. Listings refresh.
- “Header row required” — first row must be the column names. Check the template.
- “Percentages don't sum to 100” — soft warning. Confirm anyway if it's intentional, or fix the row.
- “Wax not in your library” — the wax field references a wax you haven't saved. Either add it in Settings → My Waxes first, or leave the column blank to import without a wax.
- “Recipe with that name already exists” — by default the importer skips duplicates. Toggle
OVERWRITE EXISTINGto update instead.
Recipe history + restore
Every save / update / oil-swap snapshots the prior state into recipe_history so you can roll back.
- 1
Open the recipe
From Recipes list → click the card.
- 2
Click the History icon
Top of the edit view, next to the recipe name. Shows the last 90 days of snapshots.
- 3
Pick a snapshot
Each snapshot shows: timestamp, who edited, the action (
create/update/swap_oil), and a diff of what changed. - 4
Restore
Click
Restore this version. The current state gets snapshotted (so you can undo the restore), then the recipe rewinds to the picked snapshot.
Delete + undo
Recipes use soft-delete. Hold the trash icon for ~1 second to delete; an undo banner appears for 8 seconds. After that the row stays in the DB with deleted_at set, so the catalog data + history aren't lost forever.