Welcome
Chow is a food diary that runs in any browser. This guide explains how to use it.
If you haven’t yet, you can open Chow now.
Diary Format
A diary is a folder of plain text files. You can read and edit them in any text editor.
A Basic Diary
The smallest diary is one file.
format 2
; Foods I eat often.
food greek-yogurt "Greek yogurt, nonfat"
170 g = 150 kcal 11 carb 0 fat 26 protein
food banana "Banana"
1 medium = 105 kcal 27 carb 0.4 fat 1.3 protein
2026-10-01
07:45 greek-yogurt 170 g
07:45 banana 1 medium ; with breakfast
Save it as main.chow in an empty folder, then open the folder in Chow.
Version
format 2 is the format version. It goes on the first line of main.chow.
Foods
A food block lists a food’s nutrients. For example, 170 g = 150 kcal 11 carb means 170 grams of yogurt have 150 kcal and 11 grams of carbohydrate.
Days
A date starts a day. Each indented line below it is something you ate. For example, 07:45 greek-yogurt 170 g means you ate 170 grams of yogurt at 7:45.
Chow separates fields with two spaces. One space also works.
Comments
A semicolon ; starts a comment.
Next
Add your own foods.
Foods
A food tells Chow the nutrients in something you eat.
food greek-yogurt "Greek yogurt, nonfat" ; source:fdc/170903
170 g = 150 kcal 11 carb 0 fat 26 protein 90 sodium 11 sugar
1 cup = 220 kcal 16 carb 0 fat 38 protein
130 sodium 16 sugar 2% calcium 6% iron
Anatomy of a Food
Each food has a handle, a name, optional tags, and one or more servings.
Handle
The handle is a short, easy-to-type name, e.g. greek-yogurt. It can contain letters, digits, _, and -. Each food and recipe needs a unique handle.
These words are reserved and can’t be handles: format, include, food, container, recipe, target, burn, metric, weight, and servings.
When you add a food in the app, Chow suggests a handle from the name. For example, Kirkland Signature Organic Peanut Butter becomes organic-peanut-butter.
To rename a handle, use chow rename or the food’s sheet in the app. Chow updates every entry and recipe that uses it.
Name
The name is what Chow displays. It goes in double quotes.
Tags
Tags go in a comment after the name, as key:value. The value can have spaces if you use quotes, e.g. brand:"Trader Joe's".
Chow looks for two tags:
sourceis where the food came from. See Sources.basisis which daily values a percentage refers to. See Nutrients.
Chow keeps other tags, like brand, but does not use them.
Servings
Each indented line indicates a serving, including an amount, =, and the nutrients in that amount. For example, 1 cup = 220 kcal means one cup has 220 kcal.
A unit can be any text, e.g. 1 medium onion or 2 slices.
Some servings can have a long list of nutrients. To continue a long serving on the next line, indent it further, like the 1 cup serving above.
Unknown and Zero
0 fat means the food has no fat. Leaving out fat means the fat is unknown.
When a nutrient is unknown, Chow shows that day’s total as “at least” the sum.
Units
Chow reads spelled-out units as their abbreviations and ignores case. For example, 170 grams is 170 g, and 1 Medium Onion is 1 medium onion.
| Written as | Read as |
|---|---|
gram, grams, gm, gms | g |
milligram, milligrams | mg |
kilogram, kilograms | kg |
milliliter, milliliters, millilitre, millilitres, cc | ml |
liter, liters, litre, litres | l |
ounce, ounces | oz |
pound, pounds, lbs | lb |
teaspoon, teaspoons | tsp |
tablespoon, tablespoons | tbsp |
Chow converts between weights: g, mg, kg, oz, and lb. It does not convert volumes, e.g. cup to tbsp, because that depends on the food.
Sources
The source tag is written backend/id.
| Backend | Database |
|---|---|
fdc | USDA FoodData Central |
off | Open Food Facts |
A food with no source was entered by hand.
Next
Log what you eat.
Entries
An entry records what you ate and when.
food greek-yogurt "Greek yogurt, nonfat"
170 g = 150 kcal 11 carb 0 fat 26 protein
food peanut-butter "Peanut butter"
1 tbsp = 95 kcal 3.5 carb 8 fat 3.5 protein
2026-10-01
08:14 greek-yogurt 255 g
08:14 peanut-butter 1 tbsp
15:00 "Office cake" 1 slice = 350 kcal 45 carb 16 fat
2026-10-02 08:20 greek-yogurt 1.5 x 170 g
Anatomy of an Entry
Each entry has a time, a handle, and a portion, e.g. 08:14 greek-yogurt 255 g.
Time
The time is 24-hour local time, HH:MM.
Handle
The handle of a food or recipe. It can be anywhere in the diary, before or after the entry.
Portion
The portion is how much you ate. Write it as an amount, e.g. 255 g, or as a count of a serving, e.g. 1.5 x 170 g.
Chow matches the portion to one of the food’s servings and scales its nutrients. For example, 255 g and 1.5 x 170 g of the yogurt above are the same amount.
If no serving has the same unit, Chow converts between weights. It does not convert volumes, so 1 tsp of the peanut butter above doesn’t work.
Days
To start a day with multiple entries, write the date on a line by itself. Each indented line below it is for that day.
You can also put the date on the entry’s line, e.g. 2026-10-02 08:20 greek-yogurt 1.5 x 170 g.
Inline Entries
Instead of defining a food for a single entry, you can put the nutrients inline with the entry.
15:00 "Office cake" 1 slice = 350 kcal 45 carb 16 fat
In the app, Quick Add in the + menu makes one. If you leave the name empty, the entry is called Quick Add.
On the command line, give the nutrients as options:
chow add Thai dinner --kcal 900 --carb 80
Or write the serving and its nutrients yourself:
chow add "Office cake" "1 slice = 350 kcal"
Unresolved Entries
If Chow can’t find a handle or match a portion, the entry is unresolved. The app marks it so you can fix it.
Chow ignores unresolved entries. The rest of the diary still loads. Chow qualifies the nutrient totals for that day, for example “>= 400 mg sodium” instead of “= 400 mg sodium”.
Next
Make a recipe.
Recipes
A recipe is a dish made from foods. If you eat the same dish more than once, this saves time. You only tell Chow the ingredients one time when preparing a dish instead of each time you eat it.
For example, imagine baking a lasagna. If you tell Chow the ingredients while preparing it, e.g. “8 oz tomato sauce”, “1 lb beef”, and “1 package noodles”, later in the week when you sit down to eat, you don’t have to log every ingredient.
Chow sums the calories and nutrients for each food in a recipe.
food ground-turkey "Ground turkey, 93% lean"
112 g = 170 kcal 0 carb 8 fat 22 protein
food black-beans "Black beans, canned"
1 can = 385 kcal 70 carb 1.5 fat 24 protein
food olive-oil "Olive oil"
1 tbsp = 120 kcal 0 carb 14 fat 0 protein
container dutch-oven "Dutch oven" 2250 g
2026-09-27 recipe grandmas-chili "Grandma's chili"
container dutch-oven
weight 4250 g
servings 6
ground-turkey 454 g
black-beans 2 can
olive-oil 1 tbsp
2026-09-28 12:30 grandmas-chili 250 g
2026-09-29 19:00 grandmas-chili 1 serving
2026-09-30 13:10 grandmas-chili 0.25 recipe
Anatomy of a Recipe
The first line says the date you made the dish, the word recipe, a handle, and a name. The indented lines below can go in any order.
Ingredients
Each ingredient has a handle and a portion, written like an entry. An ingredient can be another recipe.
If any ingredient leaves out a nutrient, the dish’s total for it shows as “at least” rather than an exact amount.
Weight (Optional)
weight is what the finished dish weighs. A recipe with a container needs a weight.
Container (Optional)
container gives a name to the pot, pan, glassware, etc., that you weighed the dish in. Chow subtracts its weight from weight. A container has an id, a name, and a weight, e.g. container dutch-oven "Dutch oven" 2250 g.
Servings (Optional)
servings is how many servings the dish makes.
Logging a Recipe
You log a recipe by its handle, like a food.
| Portion | Requires | Means |
|---|---|---|
1 serving | servings | the dish divided by servings |
1 recipe | the whole dish | |
a weight, e.g. 250 g | weight | that weight of the dish |
For example, the chili above weighs 4250 g in a 2250 g container, so the dish is 2000 g. 250 g is an eighth of it.
Making a Dish Again
Each time you make a dish, you write a new recipe with a new handle and date. Editing an old recipe isn’t a good idea, since it changes every entry that logged it.
Chow treats recipes with the same name, ignoring case and extra spaces, as versions of the same dish.
Next
Set targets.
Targets, Burns, and Readings
2026-01-01 target 2000 kcal 275 carb 78 fat 50 protein
28 fiber 2300 sodium
2026-06-01 target 1800 kcal 120 protein
2026-09-23
07:10 metric weight 178.4 lb
07:30 burn 400 kcal "Morning walk"
Targets
A target sets your daily goals from its date onward.
A target only changes the nutrients it lists. For example, from June 1 the goals above are 1800 kcal and 120 g protein. Carbohydrate, fat, fiber, and sodium keep their January 1 goals.
Before your first target, the goals are the US FDA daily values printed on nutrition labels since 2016. These assume a 2000 kcal diet and include 50 g added sugar and 550 mg choline. Each nutrient with a daily value gets a goal of 100%.
Each date can have at most one target.
Burns
A burn is energy you spent, e.g. exercise: 07:30 burn 400 kcal "Morning walk". It raises that day’s kcal goal.
Readings
A reading is a body measurement, e.g. 07:10 metric weight 178.4 lb. You must always write the unit.
| Metric | Measures | Units |
|---|---|---|
weight | body weight | kg, lb |
bodyfat | body fat | % |
waist | waist circumference | cm, in |
glucose | blood glucose | mg/dL, mmol/L |
height | height | cm, in |
Chow calculates body mass index from your weight and latest height.
Next
Split your diary into files.
Files
A diary is a folder. Chow reads main.chow and the files beside it as one diary.
; main.chow
format 2
; foods.chow
food greek-yogurt "Greek yogurt, nonfat"
170 g = 150 kcal 11 carb 0 fat 26 protein
; entries/2026.chow
2026-09-14 08:20 greek-yogurt 255 g
Layout
Chow writes new records to these files.
| File | Records |
|---|---|
main.chow | format version |
foods.chow | foods |
containers.chow | containers |
entries/<year>.chow | entries |
burns/<year>.chow | calorie burns, e.g. exercise |
metrics/<year>.chow | readings |
targets/<year>.chow | targets |
recipes/<year>.chow | recipes |
Chow reads every .chow file in those folders. You can move records between files, or keep everything in main.chow.
Include
To add a file outside this layout, use include, e.g. include shared/foods.chow. The path is relative to the file that has the include.
Edits
When Chow edits a file, it only changes the lines it has to. It preserves your spacing, alignment, and comments.
If two devices edit the same entry while offline, the entry can appear twice after sync. Delete the extra one.
Appendix
Nutrients
A nutrient is a number and an id, e.g. 150 kcal or 11 carb. The id sets the unit. Chow only accepts the ids listed here.
food multivitamin "House brand multivitamin" ; basis:rdi1993
1 tablet = 0 kcal 100% vit_c 100% iron 50% calcium
With a Daily Value
You can write these as a percentage of the daily value, as on a nutrition label, e.g. 15% iron.
fda2016 is the set on US labels since 2016. rdi1993 is the older set. To use the older set, add basis:rdi1993 to the food.
| Id | Nutrient | Unit | fda2016 | rdi1993 |
|---|---|---|---|---|
carb | carbohydrate | g | 275 | 300 |
fat | total fat | g | 78 | 65 |
protein | protein | g | 50 | 50 |
fiber | fiber | g | 28 | 25 |
satfat | saturated fat | g | 20 | 20 |
sodium | sodium | mg | 2300 | 2400 |
cholesterol | cholesterol | mg | 300 | 300 |
potassium | potassium | mg | 4700 | 3500 |
calcium | calcium | mg | 1300 | 1000 |
iron | iron | mg | 18 | 18 |
magnesium | magnesium | mg | 420 | 400 |
zinc | zinc | mg | 11 | 15 |
copper | copper | mg | 0.9 | 2 |
manganese | manganese | mg | 2.3 | 2 |
selenium | selenium | µg | 55 | 70 |
iodine | iodine | µg | 150 | 150 |
phosphorus | phosphorus | mg | 1250 | 1000 |
vit_a | vitamin A | µg RAE | 900 | 1500 |
vit_c | vitamin C | mg | 90 | 60 |
vit_d | vitamin D | µg | 20 | 10 |
vit_e | vitamin E | mg | 15 | 20.1 |
vit_b1 | thiamin | mg | 1.2 | 1.5 |
vit_b2 | riboflavin | mg | 1.3 | 1.7 |
vit_b6 | vitamin B6 | mg | 1.7 | 2 |
vit_b12 | vitamin B12 | µg | 2.4 | 6 |
Without a Daily Value
These can’t be percentages.
| Id | Nutrient | Unit |
|---|---|---|
kcal | energy | kcal |
sugar | total sugars | g |
addedsugar | added sugars | g |
netcarb | carbohydrate less fiber | g |
starch | starch | g |
transfat | trans fat | g |
monofat | monounsaturated fat | g |
polyfat | polyunsaturated fat | g |
omega6 | omega-6 fat | g |
choline | choline | mg |
Syntax
This page lists the rules of the format. For examples, see Diary Format.
Lines
- Files are UTF-8 text.
- Windows line endings work. Chow writes Unix line endings.
- Whitespace is spaces or tabs.
;starts a comment that runs to the end of the line.- Blank lines are ignored.
- Servings, recipe lines, and the lines of a day are indented. A continued nutrient list is indented further. Everything else starts in the first column.
- A serving or unit can contain spaces. It ends at
=, atx, or at the end of the line.
Grammar
The grammar is in EBNF. ws is one or more spaces or tabs.
diary = [ marker ] { line } ;
marker = "format" ws "2" [ trail ] newline ; (* the root file only *)
line = blank | comment | include | food_block | recipe_block
| container | target | timed | day_block ;
comment = ws? ";" text newline ;
include = "include" ws path [ trail ] newline ;
food_block = food_header serving_line { serving_line } ; (* at least one serving *)
food_header = "food" ws handle ws name [ ws ";" ws tags ] newline ;
serving_line = ws serving ws "=" [ ws nutrients ] [ trail ] newline
{ continuation } ;
continuation = deeper nutrients [ trail ] newline ; (* no "=" *)
recipe_block = date ws "recipe" ws handle ws name [ trail ] newline
{ recipe_line } ; (* at least one ingredient *)
recipe_line = ws ( "container" ws container_id
| "weight" ws number ws weight_unit
| "servings" ws number
| handle ws portion ) [ trail ] newline ;
container = "container" ws container_id ws name ws number ws weight_unit
[ trail ] newline ;
target = date ws "target" ws nutrients [ trail ] newline
{ continuation } ;
timed = date ws record ;
day_block = date [ trail ] newline { ws record } ; (* a date alone on its line *)
record = time ws ( entry | inline | burn | reading ) ;
entry = handle ws portion [ trail ] newline ;
inline = name ws serving ws "=" [ ws nutrients ] [ trail ] newline
{ continuation } ;
burn = "burn" ws number ws "kcal" ws name [ trail ] newline ;
reading = "metric" ws metric_id ws number ws metric_unit [ trail ] newline ;
portion = number ws "x" ws serving (* 2 x 170 g *)
| serving ; (* 340 g, 1 tsp *)
serving = number ws unit ; (* "170 g", "1 medium onion" *)
unit = word { ws word } ;
handle = idchar { idchar } ; (* not a keyword *)
container_id = idchar { idchar } ;
metric_id = idchar { idchar } ;
idchar = letter | digit | "_" | "-" ; (* ASCII *)
metric_unit = char { char } ; (* no whitespace *)
weight_unit = unit ; (* one that folds to g, kg, mg, oz or lb *)
name = '"' { char - '"' } '"' ;
tags = tag { ws tag } ;
tag = key ":" ( bareword | '"' { char - '"' } '"' ) ;
nutrients = nutrient { ws nutrient } ;
nutrient = ( number | number "%" ) ws nutrient_id ; (* "150 kcal", "15% iron" *)
nutrient_id = idchar { idchar } ;
date = digit digit digit digit "-" digit digit "-" digit digit ;
time = digit digit ":" digit digit ; (* 24-hour, HH:MM, local *)
number = digit { digit } [ "." digit { digit } ] ; (* never negative *)
trail = ws? ";" text ;
Errors
Chow rejects a diary with any of these, and reports the file and line:
- A line that matches no record
- A date that isn’t on the calendar, or a time outside
00:00to23:59 - A number, portion, or serving it can’t read
- An unknown nutrient id, or a percentage of a nutrient with no daily value
- A
basisother thanfda2016orrdi1993 - A burn in a unit other than
kcal - An unknown metric, or a unit the metric doesn’t accept
- A serving outside a food, or a food with no serving
- A reserved word as a handle
- An inline entry with
x - A
formatline anywhere but the top ofmain.chow - Two foods or recipes with the same handle
- Two servings of one food that are the same
- Two containers with the same id, or two targets on the same date
- An
includethat loops back to its own file, or names a file Chow can’t read - A recipe with no ingredient, a repeated
container,weight, orservingsline, acontainerwithoutweight, or aweightnot in a weight unit - A
servingscount or weight that isn’t above zero
An entry with an unknown handle or a portion that doesn’t match is not an error. It is unresolved.