Contents
Garden HandbookOverview

Write in Markdown | Push to Update the Site

Write posts, short notes, and columns in Markdown inside your own Git repository.

Garden is a Claude-style blog framework where you write posts in Markdown and describe components in plain language.

A Complete Example

The four steps in this section come from a real post, and every command output is taken verbatim from an actual run.

1.The Author Writes an Idea

Drop an unnamed garden fence where the interactive block should go and state what the reader adjusts and sees:

## Writing Pace

```garden
Let the reader drag daily word count and writing days per week to see how many weeks an 8,000-word article takes.
```

2.The Agent Scans and Writes Back the Component

Tell the Agent to compile content/posts/writing-pace.md. Following the garden-ui skill in the repository, the Agent first runs npx garden ui scan to read the line number, original wording, and hash:

$ npx garden ui scan content/posts/writing-pace.md
{
  "file": "content/posts/writing-pace.md",
  "draft": false,
  "blocks": [
    {
      "lang": "garden-idea",
      "status": "uncompiled",
      "startLine": 9,
      "intentHash": "8866427a",
      "intent": "Let the reader drag daily word count and writing days per week to see how many weeks an 8,000-word article takes.",
      "section": "Writing Pace"
    }
  ]
}

Next, the Agent reads the component catalog from npx garden ui prompt, writes a garden interactive block, and runs npx garden ui apply with --intent-hash to replace only that fence while leaving the rest of the file byte-for-byte untouched:

$ npx garden ui apply content/posts/writing-pace.md --intent-hash 8866427a --file new.md
{"ok":true,"file":"content/posts/writing-pace.md","kind":"garden","line":9}

3.The Pre-commit Hook Checks and Prints a Fix Prompt

On the first garden sync or garden dev run, Garden writes exec npx --no-install garden ui check --staged --quiet to .git/hooks/pre-commit. If the author commits before step 2, the hook blocks the commit and prints a ready-to-paste prompt for the AI:

$ git commit -m "Writing pace"
content/posts/writing-pace.md:9  -  garden-idea  uncompiled idea remaining

──────────────────────── Fix prompt for AI ────────────────────────
Handle the Garden post blocks listed below: compile uncompiled ideas, and fix interactive blocks that have errors.

Rules:
- First run npx garden ui prompt and read the component catalog and rules; if the repo has the garden-ui skill, follow its flow.
- Change only the listed blocks. Write them back with npx garden ui apply <post> --id <id> (use --intent-hash for ideas without an id). Do not edit the post by hand.
- Keep the author's meaning. When done, run npx garden ui check <post> until it passes.
- If you cannot access this repository, reply with only the finished fence for each block.

1. content/posts/writing-pace.md, lines 9–11, intent-hash: 8866427a
   - garden-idea: this idea is not compiled yet; compile it into garden interactive or another garden component (or put the sentence back into the prose).

Current fence:

```garden
Let the reader drag daily word count and writing days per week to see how many weeks an 8,000-word article takes.

────────────────────────────────────────────────────────────
Wrote .garden/ui-fix-prompt.md. To commit anyway, run git commit --no-verify.


The same prompt is saved to `.garden/ui-fix-prompt.md` and copied to the clipboard when a clipboard command is available. Once the Agent applies the block and the author commits again, the hook exits silently with code `0`.

### 4. The Rendered Result

The `garden interactive` fence written back in step 2 renders directly on the article page as an interactive calculator:

```garden interactive #writing-pace
caption: Writing a few hundred extra words each day finishes sooner than adding another writing day per week.
intent: |
  Let the reader drag daily word count and writing days per week to see how many weeks an 8,000-word article takes.
---
<State daily={500} days={3} />
<Let weekly={daily * days} />
<Let weeks={ceil(8000 / weekly)} />

<Slider bind="daily" label="Words per day" min={200} max={2000} step={100} unit="words" />
<Slider bind="days" label="Days per week" min={1} max={7} step={1} unit="days" />

<Stat label="Weeks to finish 8,000 words" value={weeks} unit="weeks" hint="Rounded up to full weeks" />

Humans and Agents Share the Same Tools

The npx garden ui scan, npx garden ui apply, and npx garden ui check commands used by the Agent are the exact commands run by the author's pre-commit hook. When the hook stops a commit, its output is the instruction for the Agent's next step. See Writing with AI.

The remaining sections cover the layout and component rules that work out of the box without an Agent.

Two-line Titles and the 740px Reading Column

Write | (with spaces on both sides) inside a title to split it across two lines and scale the font size to fit the longer line. Body copy stays inside a 740px column, while wide figures expand symmetrically into the side margins without overlapping the navigation or table of contents.

Transparent-background line drawings automatically get a warm paper backing in dark mode, so you do not need separate dark assets:

Diagram of the 740px reading column, 1040px wide figure zone, and 1340px wide table zone (transparent-background dark-line SVG, backed with #faf9f5 in dark mode).

Wide Tables Expand Symmetrically

When a table is wider than the reading column without wrapping, it expands into both margins up to 1340px on desktop:

Content TypeSource LocationHow the Page Handles Long-form and Media DetailsTypical Use
Long-form postscontent/posts/<slug>.md and a matching asset folderReads local image dimensions at build time to prevent layout shift, splits titles on |, widens figures and tables, and renders KaTeX math and Mermaid diagramsSystem design notes, code walkthroughs, debugging postmortems, and book notes
Short thoughtscontent/thoughts/<slug>.mdRenders multi-image grids, native image / audio / video players, and external link preview cardsShort observations, terminal screenshots, audio clips, and saved links
Ordered columnscontent/columns.yamlChains multiple posts from content/posts/ in reading order with series progress and previous/next navigationMulti-part tutorials, topic series, and chaptered notes

Code Blocks and the Diff Toggle

Write a one-sentence garden idea right below an updated code block to describe what changed, and the Agent generates the adjacent diff fence; you can also write the diff fence by hand. When a code block is immediately followed by a diff block, the page combines them into a single frame with tabs for the full code and the diff against the previous version, while the copy button always copies the new code.

pages:
  garden:
    title: "Write in Markdown | Push to Update the Site"
    subtitle: "Write posts, short notes, and columns in Markdown inside your own Git repository."

Note

A diff fence must sit immediately after a complete code block; a standalone diff fence triggers a diff-orphan error in npx garden check.

Custom Callout Titles

Write text on the same line after > [!TIP] (or place a bold line immediately below) to replace the default callout title. Supported types include NOTE, TIP, IMPORTANT, WARNING, and CAUTION.

Structured Components in Markdown

Use ```garden <name> fences to insert metrics, side-by-side comparisons, timelines, or charts. Here is a garden stat block:

Reading Column
740px
Default width for paragraphs, code blocks, and lists
Wide Figure Zone
1040px
Screenshots display at half their pixel width and expand up to this limit above ~2000px
Wide Table Zone
1340px
Maximum width for wide multi-column tables expanding symmetrically on desktop

See Components Overview in the sidebar for all 12 built-in components and their live examples.

From Init to Daily Writing

Your site repository stores only configuration, Markdown posts, and static assets, while hd-garden provides the renderer and build scripts. Initialize and preview a site locally:

npx hd-garden init my-blog
cd my-blog
npm install
make dev

Run make update when a post is ready; it runs the full check and build before committing and pushing. Read the chapters for details:

Contents