Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  • source is where the food came from. See Sources.
  • basis is 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 asRead as
gram, grams, gm, gmsg
milligram, milligramsmg
kilogram, kilogramskg
milliliter, milliliters, millilitre, millilitres, ccml
liter, liters, litre, litresl
ounce, ouncesoz
pound, pounds, lbslb
teaspoon, teaspoonstsp
tablespoon, tablespoonstbsp

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.

BackendDatabase
fdcUSDA FoodData Central
offOpen 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.

PortionRequiresMeans
1 servingservingsthe dish divided by servings
1 recipethe whole dish
a weight, e.g. 250 gweightthat 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.

MetricMeasuresUnits
weightbody weightkg, lb
bodyfatbody fat%
waistwaist circumferencecm, in
glucoseblood glucosemg/dL, mmol/L
heightheightcm, 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.

FileRecords
main.chowformat version
foods.chowfoods
containers.chowcontainers
entries/<year>.chowentries
burns/<year>.chowcalorie burns, e.g. exercise
metrics/<year>.chowreadings
targets/<year>.chowtargets
recipes/<year>.chowrecipes

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.

IdNutrientUnitfda2016rdi1993
carbcarbohydrateg275300
fattotal fatg7865
proteinproteing5050
fiberfiberg2825
satfatsaturated fatg2020
sodiumsodiummg23002400
cholesterolcholesterolmg300300
potassiumpotassiummg47003500
calciumcalciummg13001000
ironironmg1818
magnesiummagnesiummg420400
zinczincmg1115
coppercoppermg0.92
manganesemanganesemg2.32
seleniumseleniumµg5570
iodineiodineµg150150
phosphorusphosphorusmg12501000
vit_avitamin Aµg RAE9001500
vit_cvitamin Cmg9060
vit_dvitamin Dµg2010
vit_evitamin Emg1520.1
vit_b1thiaminmg1.21.5
vit_b2riboflavinmg1.31.7
vit_b6vitamin B6mg1.72
vit_b12vitamin B12µg2.46

Without a Daily Value

These can’t be percentages.

IdNutrientUnit
kcalenergykcal
sugartotal sugarsg
addedsugaradded sugarsg
netcarbcarbohydrate less fiberg
starchstarchg
transfattrans fatg
monofatmonounsaturated fatg
polyfatpolyunsaturated fatg
omega6omega-6 fatg
cholinecholinemg

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 =, at x, 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:00 to 23: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 basis other than fda2016 or rdi1993
  • 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 format line anywhere but the top of main.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 include that loops back to its own file, or names a file Chow can’t read
  • A recipe with no ingredient, a repeated container, weight, or servings line, a container without weight, or a weight not in a weight unit
  • A servings count 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.