Trunk Setup
The trunk is your main branch that defines the overall Quarto site structure.
Installation
uv init --lib
uv add quarto-graftCreate a New Trunk
Initialize a trunk in your current directory:
# Interactive mode (will prompt for site name and template)
quarto-graft trunk init
# Or provide all options
quarto-graft trunk init "My Documentation" --template defaultThis creates files in your current directory:
.
├── _quarto.yaml # Site config with collar markers
├── grafts.yaml # Graft configuration
├── grafts.lock # Build manifest (auto-generated)
├── .gitignore
├── dist/ # Build output and worktree cache (gitignored)
└── docs/ # Website content
├── index.qmd
├── favicon.svg
└── grafts__/ # Auto-generated graft content
Note: The command works in your current directory and does NOT create a subdirectory. Make sure you’re in your git repository root before running it.
Understanding the Trunk Template
The trunk template defines your site’s structure. Key file: _quarto.yaml
project:
type: website
output-dir: _site
website:
title: "My Project"
sidebar:
contents:
- docs/index.qmd
- section: My Grafts
contents:
- _GRAFT_COLLAR: main # Collar attachment point
- section: Notes
contents:
- _GRAFT_COLLAR: notes # Another collarCollars (_GRAFT_COLLAR) are attachment points where grafts connect. When you create a graft, you specify which collar it attaches to.
First Build
quarto-graft trunk build # Build all grafts
quarto preview # Preview the siteOn first build, no grafts exist yet, so collars will be empty.
Customizing Your Trunk
Using Custom Templates
You can create custom trunk templates for your organization:
# Use a custom template
quarto-graft trunk init "My Docs" --template /path/to/template
# Template structure
my-trunk-template/
├── _quarto.yaml # Jinja2 template
├── docs/
│ └── index.qmd # Jinja2 template
└── grafts.yaml # Jinja2 templateTemplates use Jinja2 variables: - { project_name } - Project name - { project_slug } - URL-safe slug - Custom variables you define
Defining Collars
Edit _quarto.yaml to add/remove collars:
website:
sidebar:
contents:
- section: Articles
contents:
- _GRAFT_COLLAR: articles
- section: Tutorials
contents:
- _GRAFT_COLLAR: tutorials
- section: Reference
contents:
- _GRAFT_COLLAR: referenceGrafts will attach to these named sections.
Publishing to GitHub Pages
Initialize git and push to GitHub:
git init git add . git commit -m "Initial trunk" git remote add origin <your-repo-url> git push -u origin mainCreate
gh-pagesbranch:git checkout --orphan gh-pages git rm -rf . git commit --allow-empty -m "Initial gh-pages" git push -u origin gh-pages git checkout mainConfigure GitHub Pages:
- Settings → Pages → Source:
gh-pagesbranch - Settings → Actions → Permissions: Enable read/write
- Settings → Pages → Source:
Build and publish:
quarto-graft trunk build quarto render quarto publish gh-pages
How It Works
- Grafts attach to collars: Each graft specifies a collar in
grafts.yaml - Build process:
quarto-graft trunk buildrenders each graft in isolation - Auto-navigation: Built content is injected after the matching collar marker
- Atomic updates: The trunk’s
_quarto.yamlis updated automatically
Render Cache
The render cache stores pre-rendered HTML on an orphan _cache branch. Pages whose source hasn’t changed are served directly from cache, dramatically speeding up incremental builds.
# Typical workflow with caching
quarto-graft trunk build # Build grafts (uses cache for unchanged pages)
quarto render # Render the site
quarto-graft trunk cache update # Store newly rendered pages in cache
# Inspect cache contents
quarto-graft trunk cache status
# Clear cache when needed
quarto-graft trunk cache clearMonitoring Build Status
Use the status dashboard to see the state of all grafts at a glance:
quarto-graft statusThis shows each graft’s build status (current, stale, broken, never built), last build time, and whether HEAD matches the last built commit.