Easy-to-manage touch screens
무료 오픈소스 터치스크린으로 USB 설정 가이드, 드래그‑드롭 편집기, 로컬 제어를 제공하며 Home Assistant용으로 제작되었습니다
CookCLI는 무료 오픈소스 CLI 도구로, 레시피에서 장보기록을 만들고 로컬 레시피 서버를 실행하며 웹사이트에서 레시피를 가져온다
CookCLI is a free, open-source command-line tool that generates shopping lists from recipes, runs a local recipe server, imports recipes from websites, and …
라이프스타일Rust · HTMLGitHub @cooklang온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Recipe Management CLI + embedded web-server in one binary
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Command line tools for working with Cooklang recipes. Full reference: CookCLI documentation.
# macOS/Linux (Homebrew)
brew install cookcli
# Download binary (all platforms)
# Visit: https://github.com/cooklang/CookCLI/releases
CookCLI provides a suite of commands to create shopping lists, reports and maintain recipes. We've built it to be simple and useful for automating your cooking and shopping routine with existing UNIX command line and scripting tools. It can also function as a webserver for your recipes, making them browsable on any device with a web browser.
Try the web interface live at demo.cooklang.org
cook login, cook server keeps your recipe folder in step with your phone and desktop through Cook Cloud sync (Cook Basic)First, install CookCLI using one of the methods below. CookCLI comes with a few sample recipes to play with. cook seed populates its target directory with recipe files and folders, so create a dedicated directory for them first:
$ mkdir my-recipes && cd my-recipes
$ cook seed ./
$ cook recipe "Neapolitan Pizza.cook"
This displays the recipe in a human-readable format:
Neapolitan Pizza
source: https://www.stadlermade.com/how-to-pizza-dough/neapolitan/
servings: 6
Ingredients:
semolina
Pizza Dough (recipe: Shared/Pizza Dough) 6 balls
flour
semolina
San Marzano tomato sauce 5 tbsp
basil leaves
mozzarella cheese 100 grams
Cookware:
outdoor oven
spatula
Steps:
1. Preheat your outdoor oven so it’s around 450/500°C (842/932°F).
[-]
2. Prepare your pizza toppings because from now on you wanna work fast.
Sprinkle some semolina on your work surface.
[semolina]
...
Create a shopping list from multiple recipes:
$ cook -v shopping-list "Neapolitan Pizza.cook" "./Breakfast/Easy Pancakes.cook""
Plan your meals with a menu file (Weekly Plan.menu):
---
servings: 2
---
==Saturday==
Breakfast: \
- @oats{1%cup} with @milk{1/2%cup} and @honey{1%tbsp}
Lunch: \
- @./lamb-chops{}
Dinner: \
- @./Neapolitan Pizza{}
==Sunday==
Breakfast: \
- @./Breakfast/Easy Pancakes{} with @maple syrup{2%tbsp}
Lunch: \
- @./Salads/Caprese{}
Dinner: \
- @./Risotto{}
Menu files let you reference recipes and inline ingredients, plan by day and meal, and generate a combined shopping list for the whole plan.
Or start the web server to browse your recipes:
$ cook server --open
Listening on http://127.0.0.1:9080
Serving Web UI on http://localhost:9080
Serving recipe files from: "/Users/chefalexey/recipes"
Download the latest release for your platform from the releases page and add it to your PATH.
Archives are named cook-<version>-<os>-<arch>[-<libc>], with a .sha256
next to each:
| Platform | Archive |
|---|---|
| Linux x86_64 (static, any distribution) | cook-<version>-linux-x86_64-musl.tar.gz |
| Linux x86_64 (glibc) | cook-<version>-linux-x86_64-gnu.tar.gz |
| Linux x86 (32-bit) | cook-<version>-linux-i686-musl.tar.gz |
| Linux ARM 64-bit (Raspberry Pi 3+ on a 64-bit OS) | cook-<version>-linux-aarch64-musl.tar.gz |
| Linux ARM 32-bit hard-float (Raspberry Pi OS 32-bit) | cook-<version>-linux-armhf-musl.tar.gz |
| macOS Apple Silicon / Intel | cook-<version>-macos-aarch64.tar.gz / cook-<version>-macos-x86_64.tar.gz |
| Windows x86_64 / x86 / ARM64 | cook-<version>-windows-x86_64.zip / -windows-i686.zip / -windows-aarch64.zip |
| FreeBSD x86_64 | cook-<version>-freebsd-x86_64.tar.gz |
Once installed, cook update keeps it current.
Using Homebrew:
brew install cookcli
Every release ships RPMs built in Fedora containers (x86_64 and aarch64). Download the one for your Fedora version and install it:
sudo dnf install ./cookcli-<version>-1.fcXX.x86_64.rpm
The package installs the cook binary and shell completions. To build the RPM
yourself (or to set up a COPR repository), see packaging/fedora.
Every release ships .deb
packages for amd64 and arm64. They install on Debian 12+ and Ubuntu 22.04+:
sudo apt install ./cookcli_<version>-1_amd64.deb
The package installs the cook binary and shell completions. To build it
yourself, see packaging/debian.
If you have Rust installed:
cargo install cookcli --locked
--locked builds against the dependency versions we tested and released with, rather than re-resolving to the newest compatible ones.
Note that this compiles CookCLI and all its dependencies from source, which needs a few GB of RAM and disk. If you are on a Raspberry Pi, an Armbian board, or anything else memory-constrained, prefer the prebuilt binaries — we publish aarch64 and armhf Linux builds.
cargo install places its build directory under $TMPDIR. On Armbian, /tmp is mounted on zram — a RAM-backed device sized to half your RAM — so a multi-gigabyte build will exhaust memory and fail, sometimes with a confusing failed to load bitcode of module ... error.
Point the build somewhere on real storage:
CARGO_TARGET_DIR=~/.cache/cookcli-build cargo install cookcli --locked
If memory is still tight, disable link-time optimisation for the build:
CARGO_PROFILE_RELEASE_LTO=false \
CARGO_TARGET_DIR=~/.cache/cookcli-build \
cargo install cookcli --locked
You'll need Rust and Node.js installed. Then:
# Clone the repository
git clone https://github.com/cooklang/CookCLI.git
cd CookCLI
# Install frontend dependencies
npm install
# Build CSS and JS (required for web UI; the build fails without them)
npm run build-css
npm run build-js
# Build the CLI with web UI
cargo build --release
# Binary will be at target/release/cook
static/css/output.css and static/js/editor.bundle.js are generated by Tailwind and esbuild and are not checked into git, so they are missing from clones and from GitHub's auto-generated tag archives — and cargo build refuses to start without them.
If Node.js is unavailable or its native toolchain has no build for your platform, use a source drop that ships those two files prebuilt:
# cook-<version>-source.tar.gz is attached to each GitHub release.
# Set VERSION to the one you want: https://github.com/cooklang/CookCLI/releases
VERSION=0.34.0
curl -LO "https://github.com/cooklang/CookCLI/releases/download/v$VERSION/cook-$VERSION-source.tar.gz"
tar xzf "cook-$VERSION-source.tar.gz"
cd "cookcli-$VERSION"
cargo build --release --locked
The crates.io package (cargo install cookcli --locked) includes them too.
The optional commands are behind Cargo features, all enabled by default. Turning them off cuts the dependency graph roughly in half (412 crates → 225) and the binary from ~23 MB to ~9 MB — useful for CI/CD, package managers, or small machines where you only want the core recipe tooling.
| Feature | Command | Notes |
|---|---|---|
server | cook server | Web UI (axum + tower). cook build still works without it. |
import | cook import | Scrape a recipe from a website. |
lsp | cook lsp | Language server for editor integrations. |
sync | cook login / cook logout | Recipe sync. Implies server — the sync loop runs inside it. |
self-update | cook update | In-place binary upgrade. |
# Core CLI only: recipe, shopping-list, search, doctor, pantry, report, build, seed
cargo build --release --no-default-features
# Core plus the web server
cargo build --release --no-default-features --features server
Everything not listed above — parsing, scaling, shopping lists, search, pantry, reports and the static site builder — is always compiled in.
For development with hot-reload of CSS changes:
# Install dependencies
npm install
# In one terminal, watch CSS changes
npm run watch-css
# In another terminal, run the development server
cargo run -- server ./seed
# Or use the Makefile
make dev_server # Builds CSS and starts server
CookCLI follows the UNIX philosophy: each command does one thing well.
cook recipeParse and display recipe files. You can view them in different formats and scale quantities.
# View a recipe
cook recipe "Pasta Carbonara.cook"
# Scale a recipe to 2x
cook recipe "Pizza.cook:2"
# Output as JSON
cook recipe "Soup.cook" -f json
# Save as Markdown
cook recipe "Cake.cook" -f markdown > cake.md
cook shopping-listGenerate shopping lists from one or more recipes. Ingredients are automatically combined and organized by store section.
# Single recipe
cook shopping-list "Dinner.cook"
# Multiple recipes with scaling
cook shopping-list "Pasta.cook:3" "Salad.cook"
# All recipes in a directory
cook shopping-list *.cook
cook serverRun a web server to browse your recipes from any device.
# Start on localhost
cook server
# Allow access from other devices on your network
cook server --host
# Only if you open it by host name instead of IP address: name that origin,
# or the server refuses to answer it
cook server --host --cors-origin http://raspberrypi.local:9080
# Use a different port
cook server --port 8080
# Open browser immideately
cook server --open
# Require sign-in before anyone can change recipes (asks for a password)
cook server user add alice
Without users, anyone who can reach the server can change your recipes. Once
you add one, visitors can still browse, but creating, editing or deleting
recipes and changing the pantry or the shopping list need a signed-in user.
Manage users with cook server user add|passwd|remove|list; a running server
picks up the changes on its own. See Signing in to make
changes.
The container image runs cook server /recipes --host, so the server is open
to everyone who can reach the container. To require sign-in:
Give the container a configuration directory. The image's user has no
home directory, so without one there is nowhere to keep the users file or
the key that signs session cookies. In docker-compose.yml:
services:
cookcli:
image: ghcr.io/cooklang/cookcli:latest
environment:
COOK_CONFIG_DIR: /config
ports:
- "9080:9080"
volumes:
- ./recipes:/recipes
- ./config:/config
Create the folder yourself before the first start (mkdir config): a
folder Docker creates belongs to root, and the container runs as UID 1000,
which cannot write to it. If your own UID is not 1000, set user: as the
comment in docker-compose.yml explains.
Add the first user. Before starting the container:
docker compose run --rm cookcli cook server user add alice
docker compose up -d
If it is already running, add the user inside it and restart it once. Sign-in turns on when the server starts with a users file, so only this first user needs a restart:
docker compose exec cookcli cook server user add alice
docker compose restart cookcli
Manage users in the running container. No restart needed: the server reloads the users file when it changes. Removing a user or changing their password signs them out everywhere.
docker compose exec cookcli cook server user add bob
docker compose exec cookcli cook server user passwd bob
docker compose exec cookcli cook server user remove bob
docker compose exec cookcli cook server user list
The password prompt does not echo what you type. docker compose exec and
run give the command a terminal; with plain docker, pass -it
(docker exec -it <container> cook server user add bob). From a script, with
no terminal, pipe the password in and pass -T:
printf '%s\n' "$PASSWORD" | docker compose exec -T cookcli cook server user add bob
cook build webGenerate a self-contained static website from your recipes. Hostable anywhere or browsable via file://.
# Build into ./_site from the current directory
cook build web
# Build a specific collection into a custom output
cook build web dist --base-path ~/my-recipes
# Build for hosting under a subpath
cook build web --base-url /recipes/
# Link back to the recipe repository from the footer
cook build web --repo-url https://github.com/user/my-recipes
cook searchFind recipes by searching through ingredients, instructions, and metadata.
# Search for recipes with chicken
cook search chicken
# Find quick recipes
cook search "30 minutes"
# Search in specific directory
cook search -b ~/recipes pasta
cook importImport recipes from websites and convert them to Cooklang format. Requires
OPENAI_API_KEY environment variable set. Or
convert a recipe to Cooklang on cook.md (Cook Basic).
# Import a recipe
cook import https://www.example.com/recipe > recipe.cook
# Import without conversion
cook import https://www.example.com/recipe --skip-conversion
cook doctorCheck your recipe collection for issues and maintain consistency.
# Validate all recipes and display parsing errors
cook doctor validate
# Check aisle configuration for shopping lists
cook doctor aisle
# Check pantry configuration
cook doctor pantry
# Run all checks
cook doctor
cook seedAdd sample recipes to explore Cooklang features. This populates the target directory with recipe files and folders, so point it at an empty or dedicated directory.
# Add to current directory
cook seed ./
# Add to specific directory
cook seed ~/my-recipes
cook reportGenerate custom outputs using templates (experimental feature).
# Generate a recipe card
cook report -t recipe-card.md.jinja recipe.cook
# Create nutrition label
cook report -t nutrition.html.jinja recipe.cook
cook pantryManage your pantry inventory, track low stock items, expiring ingredients, and find recipes you can make.
# Show items that are low or out of stock
cook pantry depleted
# Check expiring items in the next 7 days
cook pantry expiring
# Find recipes you can make with available ingredients
cook pantry recipes
# Include partial matches (recipes where most ingredients are available)
cook pantry recipes --partial --threshold 60
# Output in machine-readable formats
cook pantry -f json depleted
cook pantry -f yaml expiring --days 14
Detailed documentation for each command is available in the docs/ directory:
CookCLI looks for configuration files in:
./config/ - in your recipe directory (highest priority)~/.config/cook/ - on Linux~/Library/Application Support/cook/ - on macOS%APPDATA%\cook\config\ - on WindowsConfiguration files:
aisle.conf - Organizes ingredients by store sectionpantry.conf - Tracks your ingredient inventory with quantitiesCOOK_CONFIG_DIRSet COOK_CONFIG_DIR to use a different global configuration directory. It
replaces the platform default above for everything CookCLI keeps there —
aisle.conf, pantry.conf, your CookCloud session, the sync database, and
cook server's users file, session key and signed-out sessions — so it gives
you a self-contained CookCLI:
COOK_CONFIG_DIR=~/kitchen/cook-config cook shopping-list dinner.cook
A local ./config/ still takes priority. An empty value means "unset", and the
platform default applies.
This is also how the test suite keeps itself away from your real session:
HOME and XDG_CONFIG_HOME cannot do the job, because the Windows
configuration directory is resolved through the Known Folder API and ignores
both.
COOK_CORS_ORIGINSet COOK_CORS_ORIGIN to name the origins cook server accepts browser
requests from, and so the host names it answers at, separated by commas — the
same values as --cors-origin, which overrides the variable:
COOK_CORS_ORIGIN=https://cook.example.com cook server --host
It exists for containers, where passing a flag means restating the image's
whole command. An empty value means "unset". --no-csrf-check has no
equivalent variable and has to be passed on the command line.
COOK_USERS_FILENames the users file cook server reads to require sign-in, in place of
users.toml in the configuration directory. cook server user edits the same
file. --users-file overrides it, and an empty value means "unset". See
Signing in to make changes.
COOK_USERS_FILE=/etc/cook/users.toml cook server --host
aisle.conf)Organizes ingredients by store section for shopping lists. Items not in any category will appear under "Other".
// In the order you walk the store
[produce]
tomatoes|tomato
basil|basil leaves // fresh, not dried
garlic
onions
[dairy]
milk
cheese
yogurt
butter
[pantry]
flour
sugar
pasta
rice
olive oil
[meat]
chicken
beef
pork
[bakery]
bread
rolls
Each [name] line starts a section, and each line under it is one ingredient,
with its other names after |. Comments start with //, on a line of their
own or at the end of one. Unlike pantry.conf, this file is not TOML: a line
starting with # or -- is read as an ingredient, and cook doctor aisle
points such lines out.
pantry.conf)Tracks your ingredient inventory with quantities, expiration dates, and low stock thresholds. Items in your pantry are excluded from shopping lists automatically.
[freezer]
ice_cream = "1%L"
frozen_peas = "500%g"
spinach = { bought = "05.05.2024", expire = "05.06.2024", quantity = "1%kg" }
[fridge]
milk = { expire = "10.05.2024", quantity = "2%L", low = "500%ml" }
cheese = { expire = "15.05.2024" }
butter = "250%g"
[pantry]
rice = { quantity = "5%kg", low = "1%kg" }
pasta = { quantity = "1%kg", low = "200%g" }
flour = { quantity = "5%kg", low = "1%kg" }
olive_oil = { quantity = "1%L", low = "250%ml" }
salt = "1%kg"
Pantry items can be specified in two formats:
item = "quantity"item = { quantity = "amount", expire = "date", bought = "date", low = "threshold" }Attributes:
quantity - Current amount in stocklow - Threshold for low stock warnings (same units as quantity)expire - Expiration datebought - Purchase dateItems listed in your pantry will be automatically excluded from shopping lists, helping you track what you already have at home. Use cook pantry depleted to see low stock items and cook pantry expiring to check expiration dates.
# Shopping list will organize by aisle and exclude pantry items
cook shopping-list "Pasta.cook"
# Check which ingredients aren't categorized
cook doctor aisle
# Use specific config directory
cook shopping-list "Recipe.cook" --aisle ./my-config/aisle.conf
# Example: Recipe calls for salt, pepper, chicken, tomatoes
# With pantry.conf containing salt and rice in your inventory:
# Shopping list will only show: pepper, chicken, tomatoes
CookCLI has different level of logging. You can pass -v to show info messages, -vv for debug and -vvv for trace. Use it if you want to submit bug report because it will help us to better understand what's going on.
Use the : notation to scale any recipe:
cook recipe "Pizza.cook:2" # Double
cook shopping-list "Pasta.cook:0.5" # Half
CookCLI works great with pipes and standard tools:
# Find all recipes with chicken and create a shopping list
cook search chicken | xargs cook shopping-list
# Convert all recipes to Markdown
for r in *.cook; do
cook recipe "$r" -f markdown > "docs/${r%.cook}.md"
done
Why not? It will help more people discover this tool and Cooklang.
We welcome contributions! See CONTRIBUTING.md for guidelines.
Areas where we'd love help:
Thanks to all the people who have contributed to CookCLI!
MIT License. See LICENSE for details.
Some source files include code from cooklang-chef, also under MIT license.