# HowToCook stores Chinese home cooking as Markdown, and splits one dish four ways

> HowToCook is a community cookbook whose recipes are plain Markdown files chosen because free-form recipe posts hide ingredients mid-instruction. The interesting decisions are the file layout, the regional splitting of single dish names, and a viewer image that publishes a port with a login printed in its own README.

**Anduin2017/HowToCook** — Programmer's guide about how to cook at home.

- Repository: https://github.com/Anduin2017/HowToCook
- Website: https://howtocook.aiursoft.com
- Stars: 102,362 · Forks: 11,102
- Language: Unknown
- License: Unlicense
- Published: 2026-08-24 · Updated: 2026-08-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/anduin2017-howtocook

## A dish is a Markdown file, and it gets a directory when it needs more than one

The repository is mostly Markdown, and the dish index exposes two different shapes. Some entries are a single file, such as `dishes/vegetable_dish/炒茄子.md`. Others are a directory holding a file of the same name, such as `dishes/vegetable_dish/虎皮青椒/虎皮青椒.md`. The second shape exists for dishes that carry more than a recipe, which means a link in the index is not a reliable signal of how much sits behind it.

New dishes begin by copying the template at `dishes/template/示例菜/示例菜.md` and editing it, and that is the entire contribution contract: bring a file, keep the shape. The stated reason for the project explains why the structure is so strict. Recipes found online are written in inconsistent ways and introduce ingredients partway through, which the author describes as extremely unfriendly to people used to formal languages. A fixed template plus a lint chain is the answer to that complaint, rather than more prose telling contributors to be careful.

## One dish name becomes four files once the methods diverge by region

红烧肉 appears four separate times in the index: 简易红烧肉, 南派红烧肉, 湖南家常红烧肉 and 徽派红烧肉. A single method did not survive contact with four regional kitchens, so the project split rather than averaged, and each variant keeps the dish name so that a search for it still lands in the right place.

鸡蛋羹 splits along a different axis, by appliance rather than by region: 鸡蛋羹, 微波炉鸡蛋羹 and 蒸箱鸡蛋羹, the same dish reached through a microwave or a steamer.

The consequence for a reader is a search problem rather than a cooking problem. Looking up a dish by name returns several files that are all correct, and the choice between them comes down to regional taste and the equipment on your counter, neither of which the filename states. Anyone automating over this repository has to treat a dish name as a group rather than a key, because no file in the index is marked canonical.

## The viewer image ships a fixed admin login and indexes for thirty minutes

Reading the collection locally takes two Docker commands:

```bash
docker pull aiursoft/howtocookviewer
docker run -d -p 5000:5000 aiursoft/howtocookviewer
```

Two details follow from that. The default username and password are `admin` and `Admin@123456!`, and the README documents no way to change them. Indexing is automatic and completes within 30 minutes of start, so an empty viewer straight after launch is expected rather than broken.

The credential is the part to act on. The documented command maps port 5000 with `-p 5000:5000` and no host restriction, so a viewer started on a laptop or a shared host is reachable by anyone who can reach that port, using a password printed in the project's own README. Since there is nothing documented to change inside the image, the only place to intervene is outside it: bind the port to localhost, or put a reverse proxy with your own authentication in front of it. Treat the documented command as a single-machine convenience, not as a deployment.

## npm run lint rewrites your branch before it reports anything

The check chain is four steps, wired together in the lint script:

```bash
npm run textlint && npm run markdownlint && npm run manuallint && echo 'Lint finished. All passed.'
```

`textlint` runs with `--fix`, so it edits files in place rather than only reporting them. `markdownlint` is scoped to `./dishes` and `./tips`, which leaves the README and the scripts under `.github` outside its reach. `manuallint` is a project script covering what the generic linters cannot. The two textlint rules installed are Japanese and Chinese spacing and bracket rules, which is the dependency list telling you plainly that this corpus is not English prose.

The consequence for a contributor is that a pull request can come back carrying edits you did not make, because the fixer ran over your branch as part of checking it. And a passing lint run is a statement about formatting and file shape, not about whether the recipe works. The rules themselves live in `.textlintrc` and `.markdownlint.json` at the repository root, and `CODE_OF_CONDUCT.md` sets the conduct expectations for the same pull request.

## npm run build regenerates the README index, not the website

`npm run build` executes `node ./.github/readme-generate.js`, whose job is to regenerate the dish index you scroll in the README. The website is a different artifact entirely: the image `aiursoft/howtocookviewer` is pulled from a registry, and nothing in this repository builds it.

That split has a practical consequence for anyone waiting to see their dish online. Adding a file and opening a pull request updates the Markdown and the generated index, but the site at howtocook.aiursoft.com reflects it only after that image is rebuilt and published, on a schedule the repository does not control.

There is also a small inconsistency worth knowing before filing anything: the `homepage` field in `package.json` reads `https://cook.aiursoft.com`, while the README links `https://howtocook.aiursoft.com/`. Two domains for one project, and the README is the one the project points readers at. Releases are versioned separately from that: 1.6.0 shipped on 2026-05-11, after 1.5.0 in June 2025 and 1.4.0 in June 2024, while the last push to the repository was on 2026-09-23.

## tips/ holds the techniques the recipes assume you already know

The recipes sit on top of a second directory the dish index never surfaces. Under `tips/` are the practical notes: 厨房准备, 如何洗碗 and 如何选择现在吃什么, the last of which is the project's answer to the question of what to cook now. Under `tips/learn/` are the individual techniques: 学习焯水 for blanching, 学习炒与煎 for stir-frying and pan-frying, 学习凉拌, 学习腌, 学习蒸, 学习煮, plus 去腥 for removing fishy smells and 食品安全 for food safety. Appliance notes cover 微波炉, 高压力锅 and 空气炸锅.

A recipe that says to blanch or to stir-fry is assuming you have read the matching note. The consequence is a dependency the index does not show you: a dish file can be complete on its own and still be unusable to someone who has never been told what 焯水 involves. Read 食品安全 first, because that one changes behaviour rather than technique, and the technique notes are the ones you will want open beside you while cooking.

## Conclusion

HowToCook is a good fit if you read recipes as data, want to diff or automate against them, and are willing to learn the techniques its tips/ directory teaches separately. It is a poor fit as a shared service, because the viewer's credential is published and the port mapping in the documented command is unrestricted, so anything beyond your own machine needs a proxy you add yourself. Before you rely on it, read the 食品安全 note and the template at dishes/template/示例菜/示例菜.md, because those two files define both the safety rules and the shape every contribution has to match.

## FAQ

### What is HowToCook?

HowToCook is a community cookbook of Chinese home cooking stored as Markdown files in a GitHub repository, written for readers who prefer explicit ingredients and steps over the free-form recipe posts found elsewhere. It is released under the Unlicense and browsable at howtocook.aiursoft.com.

### How do I browse HowToCook recipes?

The project points readers at its website at https://howtocook.aiursoft.com/. To run the collection locally instead, install Docker, pull the aiursoft/howtocookviewer image and map port 5000 with docker run -d -p 5000:5000, after which indexing finishes automatically within 30 minutes of start.

### How do I add a recipe to HowToCook?

Copy and edit the existing template at dishes/template/示例菜/示例菜.md, then open a pull request. The project expects the lint chain to pass first, which runs textlint with --fix, markdownlint across ./dishes and ./tips, and its own manuallint script, and the textlint step rewrites files in place.

### What license is HowToCook released under?

The Unlicense, recorded both in the LICENSE file at the repository root and in the license field of package.json, where the package name is how-to-cook and the version is 1.6.0.

## Sources

- [Official documentation](https://howtocook.aiursoft.com)
- [Official README](https://github.com/Anduin2017/HowToCook#readme)
- [Project repository](https://github.com/Anduin2017/HowToCook)
- [Release notes](https://github.com/Anduin2017/HowToCook/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/anduin2017-howtocook
