Formulation

Formulation is a culinary recipe-management application for building, scaling, costing, and analyzing professional recipes. It models ingredients and sub-recipes as reusable entities instead of embedding duplicated ingredient data in every recipe.

The project includes two independent Astro applications:

  • A SQLite-backed management application for recipes, ingredients, purchasing, nutrition, costs, preparation actions, conversions, and recipe books.
  • A read-only static cooking site generated from the same culinary data.

Capabilities

  • Structured recipes with components, sub-recipes, ordered preparation steps, yields, tags, and shelf life
  • Recipe scaling using amounts, standard percentages, or baker's percentages
  • Weight, volume, count, density, and ingredient-specific unit conversions
  • Preparation yields and loss or gain factors
  • Recursive nutrition and recipe costing
  • USDA FoodData Central mappings with source provenance
  • Ingredient aliases, purchasing packages, suppliers, and price history
  • Nutrition labels and missing-data indicators

The culinary data model documents entity boundaries, measurement semantics, provenance, and portability conventions.

Requirements

  • Node.js 22.12 or newer
  • npm 9.6.5 or newer
  • Python 3 for schema and content validation utilities

Install dependencies:

npm ci
python3 -m pip install --user -r requirements-dev.txt

Database

SQLite is the canonical writable store. The database is located at var/recipe-book.sqlite and is intentionally excluded from Git. Numbered SQL migrations in migrations/ define its schema.

Create a new local database from the portable culinary dataset:

npm run db:reset

This command replaces an existing local database. For an existing database, apply pending migrations without replacing data:

npm run db:migrate

npm run db:sync is an alias for the safe migration command. YAML under culinary/ is retained as portable seed and interchange data; normal edits in the management application write to SQLite.

See Local application for more detail.

Development

Run the management application:

npm run dev:app

Open http://localhost:4322/app/.

To stop any process listening on the application port and start a fresh Astro development server:

npm run restart:app

Run the static cooking site separately:

npm run dev:site

Open http://localhost:4321/. The site command creates a read-only projection at generated/site-projection.json before Astro starts.

Validation and builds

Run application and site type checks, unit tests, and both production builds:

npm run check
npm test
npm run build

Build output is separated by application:

  • dist/app/ — standalone Node server for the management application
  • dist/site/ — static public cooking site

Culinary data tools

Validate portable culinary entities, schemas, and cross-references:

scripts/validate-content

Search USDA FoodData Central and import a nutrition mapping:

USDA_FDC_API_KEY=... scripts/usda-fdc search "all-purpose flour"
USDA_FDC_API_KEY=... scripts/usda-fdc import flour_all_purpose 790018

Use --reviewed only after confirming that the selected record describes the canonical ingredient. Never commit the USDA API key.

Purchasing candidates can be proposed from the sibling ledger receipt archive and reviewed in the application:

scripts/receipt-products propose
scripts/receipt-products apply ~/Downloads/purchasing-decisions.json

The review interface is available at /tools/purchasing-review/.

Knowledge export

Generate the recipe corpus used by external knowledge systems:

scripts/corpus-export

The Gitea Actions workflow in .gitea/workflows/sync-knowledge.yml can publish that corpus to an Open WebUI knowledge base. Configure these repository Actions variables:

OPEN_WEBUI_URL
GOURMAND_KB_ID

Configure the API key as the KNOWLEDGE_SYNC_OPEN_WEBUI_API_KEY Actions secret. Generated exports are not committed.

S
Description
Create ingredients and nutrition data to compose weight-based recipes, or *formulations*
Readme
4.2 MiB
Languages
TypeScript 46.4%
Astro 21%
CSS 19.4%
JavaScript 8.5%
Python 4.6%