Documentation

Document Templates

A project can define document templates — a title, an optional skeleton body, and the Custom Fields a document of that kind is expected to fill in. A document declares the template it follows with the template: frontmatter key, and the CLI syncs that key in both directions.

A project with no templates behaves exactly as before: nothing about templates appears anywhere.

Requires CLI 1.3.0 or newer and a server that supports templates. Against an older server the CLI degrades cleanly — see Older servers below.

Browse the project’s templates

meldoc templates list
  adr       Architecture Decision Record
* how-to    How-To Guide
  runbook   Operational Runbook

* = project default (how-to)

The starred entry is the project default. meldoc templates show prints one template in full, skeleton included:

meldoc templates show adr
alias:       adr
title:       Architecture Decision Record
description: One decision, its context and its consequences
fields:      status, decided-on

skeleton:
  ## Context

  ## Decision

  ## Consequences

fields lists the custom field keys the template carries. A template with no skeleton says so, and meldoc new --template then writes the key with an empty body.

With several projects configured, both subcommands need --project — the registry belongs to a project, and the same template alias may exist in more than one. See Several Projects in One Repository.

Create a document from a template

meldoc new --alias adr-0007-drop-redis --template adr

This writes template: adr into the frontmatter and seeds the body from the template’s skeleton:

---
alias: adr-0007-drop-redis
title: adr-0007-drop-redis
template: adr
---

## Context

## Decision

## Consequences

You can also add or change template: by hand in any document and push it.

How template: syncs

The key travels in both directions, and meldoc pull is authoritative about it:

  • A document that has a template on the server gets the key written into the file.
  • A document that has no template on the server gets the key removed.

Removal is deliberate: template has no default value to leave out, so the file states either the assignment or its absence, and nothing is hidden.

Expect frontmatter changes in documents you did not edit, the first time you pull against a server that has templates. How much at once depends on the pull. A full pull — --force, or a fresh clone with no cursor — touches every document that has a template, so it lands as one large diff. An ordinary incremental pull does not: unchanged documents are not in the change set, so the key appears document by document as those documents happen to change. Most repositories see it trickle in — so if you are reviewing a diff and wondering where a template: line came from, this is where.

One consequence worth knowing: a hand-written template: naming an alias the project does not have is not accepted by the server. push warns and leaves the assignment alone, so the next pull deletes the line.

What validate checks

meldoc validate

Two template checks, both warnings:

Warning Meaning
template: names an alias the project does not have Typo, or a template that was removed from the project
Bare template: (YAML null) or a non-string value Reaches the server as nothing at all, while looking like it says something

Neither can fail a push or a ci run, by design: the CLI runs over batches of hundreds of files and over repositories that predate the feature, so one typo in one document must not fail a whole publish. --skip-validate is irrelevant to templates for the same reason.

--strict does not change this. It escalates content findings — broken links, broken assets, an unresolvable replacedBy — and neither template check is one of those, so both stay warnings under every combination of flags.

Working offline

The registry is cached on disk, refreshed by meldoc pull and by meldoc templates list. That cache is what lets meldoc validate and meldoc new --template work with no network.

One file per project, since the registry belongs to a project:

Config Cache file
Names a project (projectAlias, or an entry under baseDirs) .meldoc/cache/templates/<projectAlias>.json
Names no project at all .meldoc/cache/templates.json

The split matters beyond tidiness. A single shared file kept only the registry of whichever project pulled last, and every other project’s cache then failed its own identity check — which turned a loud “this cache is not yours” into a silent skip of every template check in the repository. A single-project config keeps the original path, so its cache survives the upgrade untouched.

When the server cannot be reached, templates list and templates show answer from the cache and say so, rather than presenting stale data as current:

(cached 2026-08-27 14:31 — server unreachable)

If the server is unreachable and no usable cache exists yet, the command asks you to pull first.

Older servers

Template support is advertised by the server. Against one that does not:

  • meldoc templates list and show report that the server needs upgrading.
  • The template: key in your files is left untouched in both directions.

That gate is what keeps a pull against an older server from stripping the key repository-wide. Mixed CLI versions are safe too: an older CLI treats template: as a key it does not recognise, preserves it, and never sends it.

What’s next?

Custom Fields — Field definitions and how documents carry values.

Command Reference — Full reference for every CLI command.

Several Projects in One Repository — Several projects in one repository.