Skip to content

MD043 - Enforce Required Document Structure

Aliases: required-headings

What this rule does

Ensures your documents contain specific required headings, helping maintain consistent structure across documentation sets.

Why this matters

  • Consistent documentation: All documents follow the same organizational pattern
  • Complete information: Ensures important sections aren't forgotten
  • Better navigation: Readers know where to find specific information
  • Team alignment: Everyone follows the same documentation template

Examples

✅ Correct

With required headings configuration:

[MD043]
headings = ["# Overview", "## Installation", "## Usage", "## License"]
# Overview

This tool helps you lint Markdown files...

## Installation

Install using npm:

## Usage

Run the following command...

## License

MIT License

❌ Incorrect

# Getting Started              <!-- Wrong heading text -->

This tool helps you...

## How to Install             <!-- Should be "Installation" -->

Install using npm...

## Examples                   <!-- Should be "Usage" -->

Run the following...

## License

MIT License

Manually corrected

# Overview                    <!-- Corrected heading -->

This tool helps you...

## Installation              <!-- Corrected heading -->

Install using npm...

## Usage                     <!-- Corrected heading -->

Run the following...

## License

MIT License

Configuration

[MD043]
headings = []      # Required heading patterns (empty disables the rule)
match-case = false  # Case-sensitive matching (default: false)

Wildcard Patterns

The headings configuration supports three wildcard patterns for flexible document structures:

* - Zero or More Headings

Matches any number of headings (including zero). Use this for optional sections that may or may not appear.

[MD043]
headings = ["# Project", "*", "## License"]

This allows:

  • # Project## License (no sections in between)
  • # Project## Features## Usage## License (multiple sections)

+ - One or More Headings

Requires at least one heading but allows multiple. Use this when content is required but flexible.

[MD043]
headings = ["# Documentation", "+", "## Contributing"]

This requires:

  • At least one section between "Documentation" and "Contributing"
  • Multiple sections are allowed

? - Exactly One Heading

Matches exactly one heading without specifying its content. Ideal for variable content like project names.

[MD043]
headings = ["?", "## Description", "## Installation"]

This requires:

  • Exactly one heading (any text) before "Description"
  • Useful for project READMEs where the title varies

Advanced Wildcard Examples

Flexible open source documentation:

[MD043]
headings = [
  "?",                  # Project name (variable)
  "## Overview",        # Required
  "*",                  # Optional sections (badges, features, etc.)
  "## Installation",    # Required
  "*",                  # Optional sections (usage, examples, etc.)
  "## License"          # Required
]

API documentation with variable endpoints:

[MD043]
headings = [
  "# API Reference",
  "+",                  # One or more endpoint sections
  "## Error Codes",
  "## Rate Limiting"
]

Adjacent wildcards form one run. Each ? and + contributes one required heading, and a run containing * or + can absorb additional headings. For example, ["?", "+"] requires at least two headings, while ["*", "?"] requires at least one.

Wildcard runs fill their required ? and + slots from left to right. A required slot may consume a heading whose text also matches the next literal; this matters when that literal occurs more than once. After the required slots are filled, the repeating portion contributed by * or + stops at the earliest heading matching the next configured literal. When more than one alignment has the same edit cost, MD043 preserves the alignment with the most exact literal matches, then prefers legal wildcard absorption and substitutions.

Diagnostic messages

When a document does not match the required structure, MD043 aligns the configured and actual heading sequences and reports every actionable difference. Exact matches and headings legally consumed by wildcards do not produce warnings.

For example, with this configuration:

[MD043]
headings = ["# Overview", "## Installation", "## Usage", "## License"]

This document:

# Overview

## Usage

## License

Reports the missing heading at ## Usage:

Heading structure does not match required structure. Missing required heading '## Installation'

Substitutions name both headings:

Heading structure does not match required structure. Expected heading '## Installation', but found '## Setup'

Unexpected headings include their position in the document, and moved headings describe their nearest configured literal neighbors:

Heading structure does not match required structure. Unexpected heading '## Notes' at position 3
Heading structure does not match required structure. Heading '## Usage' is out of order; expected between '## Installation' and '## License'

An unsatisfied ? or + produces its own warning. Missing requirements attach to the next actual heading; trailing requirements attach to the last heading, and headingless nonempty documents use line 1.

Automatic fixes

MD043 does not automatically restructure documents. Its fix operation preserves the original content because inserting, renaming, or moving headings can change document meaning.

Special cases

  • Empty configuration disables this rule
  • Wildcards (*, +, ?) provide flexible pattern matching
  • Order of headings matters - patterns are matched sequentially
  • Case sensitivity controlled by match-case option
  • The complete heading string is matched, so a different heading level is a normal mismatch
  • Invalid heading syntax is ignored by MD043
  • All wildcards pattern (e.g., ["*"]) allows any structure

Learn more

  • MD001 - Keep heading levels organized
  • MD003 - Use consistent heading styles
  • MD025 - Use only one main title