
Markdown's syntax is easy to learn, and even though the syntax is forgiving, linting can help you avoid unexpected issues.
markdownlint and its CLI tool markdownlint-cli is the most common tool used for linting Markdown files. As of writing, markdownlint validates Markdown files against a list of 53 rules . markdownlint-cli can be installed and used locally, but it's also easy to integrate into CI/CD pipelines.
See "Common Markdown Mistakes" for a list of the most common Markdown syntax mistakes I see people make.

Common Markdown Mistakes
Nov 9, 2020 · 4 min read
Markdown provides simple syntax for writing structure documents, but most written markdown would not pass a linter check. Here's a list of 11 common syntax mistakes and how to fix them.
Usage
markdownlint-cli has instructions for how to install via npm and Homebrew , but I'll focus on running it via Docker for OS portability. You can run markdownlint-cli in a container to lint Markdown files in your current directory like this:
docker run --volume "$PWD:/workdir" \
ghcr.io/igorshubovych/markdownlint-cli:latest \
"**/*.md"If you want to disable certain markdownlint rules, you can do so like this:
docker run --volume "$PWD:/workdir" \
ghcr.io/igorshubovych/markdownlint-cli:latest \
--disable MD013 MD033 MD041 -- \
"**/*.md"Note the required -- which terminates the list of space-separated rule names.
Example output
Let's define a markdown file sample.md with the contents:
#Sample
This is a sample Markdown file.
It has a number of formatting issues.
### Sub-headingHere's the example output from markdownlint-cli:
$ docker run --volume "$PWD:/workdir" ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md"
sample.md:1:1 MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#Sample"]
sample.md:1 MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "#Sample"]
sample.md:4 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 2]
sample.md:7:1 MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: "### Sub-heading"]Adding to GitHub Actions
Linters become a lot more powerful when you add them to your CI pipelines. A linter without enforcement will surely be ignored over time.
Here's a sample of how you could add markdownlint-cli to a GitHub Actions .github/workflows/test.yml (feel free to change the filename):
name: Project CI
on:
pull_request:
types:
- opened
- synchronize # HEAD has changed, e.g. a push happened
- reopened
jobs:
markdown-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: docker run --volume "$PWD:/workdir" ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md"Then you can add a branch protection rule to prevent pull request merges without certain passing jobs.




