How to lint markdown before you commit
- Step 1Grab the changed Markdown — Copy the doc you are about to commit (or the relevant section) and choose Paste text, or Upload file for a single
.md/.mdx/.markdown/.txt. - Step 2Run the linter — Click Run MD Lint. No configuration — the 12-rule set is fixed, which keeps local and CI results identical.
- Step 3Read the line-numbered report — Each entry is
**Line N** ·MDxxx— message. Because line numbers match your file, you can jump straight to the offending line in your editor. - Step 4Apply fixes and stage — Paste the
→ Suggested fix:lines for MD009/MD010/MD018/MD019; fix the rest by hand. Re-stage the file once the report is clean. - Step 5Wire CI to the API — For automation, call the linter through the public API or MCP in a CI step and fail the job on a non-empty report — the rules match what you saw in the browser.
- Step 6Use the CLI for true local hooks — For a real
.git/hooks/pre-commitacross many files, install the upstream markdownlint CLI; this tool's rule IDs line up so the conventions stay consistent.
Every rule the linter checks (12 total)
The browser linter scans your Markdown line by line and applies these 12 markdownlint-style rules. Only four rules carry an auto-generated suggested-fix string in the report; the rest are reported for you to fix by hand. There are no rule toggles — the set is fixed.
| Rule | Triggers when | Suggested fix in report? |
|---|---|---|
MD001 | A line is an H2–H6 heading (heuristic for heading-increment problems) | No — manual |
MD009 | A line ends with one or more trailing spaces or tabs | Yes — line trimmed |
MD010 | A line contains a hard tab character | Yes — each tab → two spaces |
MD011 | A reversed link (text)[url] appears instead of [text](url) | No — manual |
MD012 | A blank line follows another blank line (consecutive blanks) | No — manual |
MD018 | An ATX heading has no space after the # markers, e.g. ##Heading | Yes — space inserted |
MD019 | An ATX heading has more than one space after the #, e.g. ## Heading | Yes — collapsed to one |
MD022 | A heading is not preceded by a blank line | No — manual |
MD025 | A second (or later) # top-level H1 appears in the document | No — manual |
MD031 | A fenced code block opener is not preceded by a blank line | No — manual |
MD033 | Inline HTML outside the allowlist (img, br, hr, a, span, div, code, pre, sup, sub) | No — manual |
MD047 | The file's last line is not empty (no final newline) | No — manual |
What the report contains vs. what it does not
The result is a plain-text report, not an edited copy of your document. It is shown in a scrollable panel with Copy and Download buttons; downloads save as <name>-lint.txt. The tool never rewrites your source.
| You get | You do not get |
|---|---|
A # Lint Report header and a total issue count | A corrected/auto-fixed copy of your Markdown |
One **Line N** · MDxxx — message entry per violation | An "Apply all fixes" button (no such control exists) |
A → Suggested fix: line for MD009/MD010/MD018/MD019 only | Rule selection, severity levels, or config files |
| A clean-bill message when zero issues are found | Multi-file / folder batch linting in one run |
Input limits by plan (markdown family)
md-lint runs entirely in your browser and processes one file per run. The character limit is enforced live in the paste box; the byte limit applies to uploaded files. Both are distinct numbers — a small file with lots of characters can still hit the char limit first.
| Plan | Max file size | Max characters | Files per run |
|---|---|---|---|
| Free | 1 MB | 500,000 | 1 |
| Pro | 10 MB | 5,000,000 | 1 (this tool takes a single file) |
| Pro + Media | 50 MB | 20,000,000 | 1 |
| Developer | 500 MB | Unlimited | 1 |
Cookbook
Developer-flavored before/after pairs — the kind of nit a reviewer would otherwise flag. Left is the staged Markdown; right is the exact report.
README heading glued to the hashes (MD018)
A fast-typed README heading with no space. It would render as literal text and earn a review comment. The fix is in the report.
Input: ##Installation Report: **Line 1** · `MD018` — No space after ATX heading marker → Suggested fix: `## Installation`
Code block with no blank line above (MD031)
Common in quick docs — a fence pushed straight under a sentence. Catch it before the reviewer does.
Input: Clone and build: ``` git clone repo && make ``` Report: **Line 2** · `MD031` — Fenced code blocks should be surrounded by blank lines
Tabs in a contributor's doc edit (MD010)
Editors configured for tabs leak them into Markdown. MD010 finds the tab and suggests two spaces.
Input (leading tab): →See CONTRIBUTING for details. Report: **Line 1** · `MD010` — Hard tabs detected (use spaces) → Suggested fix: ` See CONTRIBUTING for details.`
No final newline (MD047)
POSIX-style 'file should end with a newline' — git and many tools prefer it. MD047 flags a non-empty last line.
Input (last line has no trailing newline): # Changelog - 1.2.0 ships caching Report: **Line 2** · `MD047` — Files should end with a single newline
Clean diff — ready to commit
When the staged Markdown passes all 12 rules, the report is one line and you can commit without a formatting round-trip.
Input: # Service README Setup, usage, and license — all well-formed. Report: # Lint Report ✓ No issues found. Your Markdown is clean.
Edge cases and what actually happens
This hosted tool is not a git hook
Not a hookIt does not install into .git/hooks and cannot run automatically on git commit. For a real local pre-commit hook, use the upstream markdownlint CLI; use this tool for ad-hoc checks or wire its API into CI.
One file per run, not the staged set
ExpectedA browser run lints a single document. To lint every staged Markdown file in one go, script a loop that calls the public API per file, or use the markdownlint CLI locally.
MD001 is a coarse heading heuristic
HeuristicMD001 flags every H2–H6 line rather than detecting an actual level skip, so it will appear often in structured docs. Do not gate a commit on MD001 alone; use it as a hint.
Code fences are not skipped
ExpectedThe scan is line-based, so tabs or #-led lines inside a fenced code sample can trigger MD010 or heading rules. When gating CI, expect some intentional in-code hits and filter accordingly.
MD009 flags two-space line breaks
ExpectedIf a doc deliberately uses trailing double-spaces for line breaks, MD009 reports them. Decide whether your contributor guidelines allow that style before treating MD009 as a hard failure.
Browser run keeps private-repo docs local
PreservedNothing is uploaded in the browser path, so docs from a private repo never leave your machine. The API path, by contrast, sends content to the endpoint — choose based on your data policy.
Large generated docs hit the size cap
400 rejectedAuto-generated API docs can exceed Free's 500,000-character / 1 MB limit; the counter turns red and Run is disabled. Pro raises this to 5,000,000 characters / 10 MB.
No auto-fix to stage
By designThe tool outputs a report, not a corrected file — there is no "Apply all fixes" step to stage. Apply the suggested-fix lines and your own edits, then re-stage. For bulk formatting use md-prettifier.
Report is plain text
ExpectedThe report is delivered as text/plain and downloads as <name>-lint.txt. It pastes cleanly into a PR comment or CI log because it is already Markdown-formatted text.
Frequently asked questions
How do I add this to a git pre-commit hook?
This hosted tool is not a git hook and cannot install into .git/hooks. For a true local hook, use the upstream markdownlint CLI. For automated checks, call this tool's public API or MCP endpoint from a CI step and fail on a non-empty report.
What about checking only changed files?
A browser run is single-file. To lint just the changed files, loop over git diff --name-only in a script and call the public API for each, or run the markdownlint CLI locally with a file glob.
Does the browser tool run a real hook automatically?
No — it is a manual, on-demand check. The automation path is the API/MCP integration in CI, not the browser UI.
Which rules does it enforce?
Twelve: MD001, MD009, MD010, MD011, MD012, MD018, MD019, MD022, MD025, MD031, MD033, MD047 — heading spacing and surrounds, whitespace and tabs, reversed links, blank-line discipline, single H1, fenced-code spacing, inline HTML, and a final newline.
Will it auto-fix before I commit?
No. It returns a report; there is no auto-apply. MD009, MD010, MD018, and MD019 include paste-ready fix lines, but you make the edits and re-stage yourself.
Are the browser and CI results the same?
Yes for the rules — the same linter backs both. One nuance: the browser path includes the MD001 heading heuristic, so keep that in mind if you gate CI strictly.
Is my Markdown uploaded in the browser?
No. The browser path runs entirely locally. The API path does send content to the endpoint, so choose the path that matches your data-handling policy.
What file types and sizes are supported?
Paste text or upload one .md/.mdx/.markdown/.txt. Free: 1 MB / 500,000 chars. Pro: 10 MB / 5,000,000. Pro + Media: 50 MB / 20,000,000. Developer: 500 MB / unlimited.
Does it detect bare URLs (MD034)?
No. MD034 is not implemented. The reversed-link rule (MD011) catches (text)[url] syntax errors, but bare-URL detection is out of scope.
Can I block a merge on lint failures?
Yes — call the API in CI and fail the job when the report lists any issues. Document a contributor convention (e.g. "resolve MD031 and MD018 before opening a PR") using the rule IDs.
What about validating that links actually resolve?
Use md-link-validator for that — md-lint only catches reversed-link syntax, not dead links.
What pairs well with this in a doc workflow?
Run md-prettifier for formatting normalization, md-toc-generator to keep a README TOC current, and md-code-block-tagger to label code fences, then re-lint.
Privacy first
All Markdown processing runs locally in your browser using JavaScript. No file is ever uploaded to JAD Apps servers — only metadata counters are saved for signed-in dashboard stats.