mdt

User Guide

Why mdt?

Documentation drift is a familiar problem with several solutions. This page explains where mdt fits and when it's the right choice.

vs. Copy-paste

The simplest approach: copy content between files by hand.

Copy-pastemdt
Setup effortNoneMinimal (mdt init)
Drift detectionManual reviewmdt check in CI
Sync effortEdit every copyEdit one provider, run mdt update
Cross-surfaceManualREADME + source docs + docs site from one provider
Scales with copiesGets worseStays constant

Copy-paste works for a single duplication. Once the same content lives in three or more places, manual synchronization dominates the maintenance cost.

vs. Docs framework includes

Frameworks like mdBook, Docusaurus, and MkDocs support file includes or content transclusion within their own ecosystem.

Framework includesmdt
Works in README.mdNoYes
Works in source-doc commentsNoYes
Works across frameworksNoYes
Works without a build stepSometimesYes (synced content is committed)
Data interpolationFramework-specificBuilt-in ({{ pkg.version }})
CI verificationFramework-specificmdt check exits non-zero

Framework includes solve the problem within one surface. mdt solves it across surfaces: your README, your crate/package docs, and your docs site all stay in sync from the same providers.

vs. Custom scripts

A common approach is a script that reads shared content from one file and injects it into others.

Custom scriptmdt
MaintenanceYou maintain itMaintained by the mdt project
DeclarativeNo — imperative logicYes — tag-based
CachingYou build itBuilt-in (file fingerprinting)
Editor supportNoneLSP (diagnostics, completions, hover, go-to-definition)
AI integrationNoneAgent skill (mdt skill) and MCP server
Watch modeYou build itmdt update --watch
TransformersYou build themBuilt-in (trim, indent, linePrefix, etc.)
Data interpolationYou build itBuilt-in (JSON, TOML, YAML, KDL, INI, text, commands)

Scripts work when you have one specific use case. mdt provides the same capability as a general-purpose tool, with editor integration, CI support, and an expanding feature set.

vs. Template engines (Tera, Handlebars, Jinja)

General-purpose template engines are powerful but solve a different problem.

Template enginesmdt
Target use caseGenerate files from templatesSync content across existing files
Preserves surrounding contentNo — replaces entire fileYes — only replaces tagged regions
Works in source commentsNot designed for itBuilt-in
Learning curveTemplate language + configHTML comment tags
Invisible in rendered docsN/A — generates outputYes — tags are HTML comments

Template engines generate files. mdt synchronizes regions within files. If your docs are already written and you want to keep specific sections in sync, mdt fits without restructuring. (mdt does use a template engine, minijinja, but only to render data into provider content when [data] is configured.)

When mdt is the right choice

mdt is a good fit when:

  • The same content appears in 2+ places (README, source docs, docs site)
  • You want CI to catch drift before it reaches users
  • You need data interpolation (versions, package names) across doc surfaces
  • You want editor support for navigating and maintaining template relationships
  • Your docs are already written and you want to adopt incrementally

When something else might be better

  • Single-surface docs — If all your docs live in one framework (e.g., only Docusaurus), framework-native includes may be simpler.
  • Full file generation — If you're generating entire files from data, a template engine like Tera or Handlebars is more appropriate.
  • One-time migration — If you just need to copy content once and it won't change, copy-paste is fine.

Edit this page on GitHub