<!--
  canonical-url: https://www.avonture.be/blog/markdown-lint
  published:     2024-02-03
  This is a static plain-Markdown mirror generated at build time.
  Visit the canonical URL above for the fully rendered page, with images and interactive components.
-->

# Markdown linter - solve formatting issue in md files

> Automatically solve Markdown formatting issues with the markdownlint tool and Docker. Learn how to check, configure, and use the --fix flag for consistent, clean .md files.

---
![Markdown linter - solve formatting issue in md files](/img/v2/clean_code.webp)

**TL;DR**

This article shows how to lint and auto-fix Markdown files using the `peterdavehello/markdownlint` Docker image: scanning a project, ignoring folders like `vendor` or `node_modules` via `.markdownlint_ignore`, disabling specific rules via `.markdownlint.json`, and applying automatic fixes with the `--fix` flag, wired up as a `make lint` target.

You are writing Markdown `.md` files (and you're so right) and you just wish to check (and autofix) some issues like having multiple blank lines, mixing bullet types (`-` and `*` in the same document), using a `#` title followed by `###` (i.e. you forget the level `##`) and many more.

There is a tool for this: Markdown lint and, a Docker image `peterdavehello/markdownlint`.

Let's learn how to use it.

*Like every linter, it's most useful when you don't have to think about it: [Git - pre-commit-hooks](/blog/git-precommit) lists a `markdownlint` hook that runs on every commit.*

By running `docker run --rm -v .:/md peterdavehello/markdownlint markdownlint .` you'll scan your current folder (recursively), search for any Markdown files and get the list of errors if any.

And the list can be huge if you're using dependencies like, for PHP, the `vendor` folder or `node_modules` for npm/yarn. Just ignore them.

## Ignore some files/folders

Create a file called `.markdownlint_ignore` in the root directory of your project with this content:

**.markdownlint\_ignore**

```
node_modules/**/*.markdown
node_modules/**/*.md
vendor/**/*.markdown
vendor/**/*.md
```

This time, please run `docker run --rm -v .:/md peterdavehello/markdownlint markdownlint --ignore-path .markdownlint_ignore .`.

The list will probably be better and only contains your files.

## Ignore some errors

You can ignore some detected errors like the use of inline HTML by creating a file called `.markdownlint.json`. You can find an example on <https://github.com/DavidAnson/markdownlint/blob/main/.markdownlint.json>. See <https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md> for more information.

To use your configuration file, now, please run `docker run --rm -v .:/md peterdavehello/markdownlint markdownlint --config .markdownlint.json --ignore-path .markdownlint_ignore .`.

## Some errors can be fixed automagically

Some errors can be fixed automagically like multiple empty lines or by trimming extra spaces at the end of lines.

The flag here is `--fix` but, pay attention, since fixes will update files you should also provide the `--user $(id -u):$(id -g)` flag so files will be updated but will still be owned by you.

## Put all together

The final instruction becomes: `docker run --rm --user $(id -u):$(id -g) -v .:/md peterdavehello/markdownlint markdownlint --fix --config .markdownlint.json --ignore-path .markdownlint_ignore .` and that's the one I'm running every time when I publish this blog.

## Make it easy

You don't need to remember the entire command of course. Using a [Makefile](/blog/tags/makefile) in your project, you can then create a new `target` where you put the command.

For this blog f.i., I'm running `make lint` in my deploy process. You can see this [here](https://github.com/cavo789/blog/blob/main/makefile#L42-L45).
