HTML and Markdown can disagree
Erik Rekola · 2026-09-12
A Markdown version can leave out part of a page or send a reader to a different link. I built markdown-parity-check to compare what the two versions actually contain.
My own tools page gave the checker something to report. A check recorded on 11 September 2026 found a Related heading and four links in its Markdown version that the HTML page leaves out. The comparison returned five errors. That dated result is recorded in the tool's README.
The difference is structural rather than missing content. The HTML page links to the same four destinations from its tool cards, so nothing was unreachable, but the Markdown reader gets a Related section the HTML reader never sees. Neither version looked broken on its own.
On this page
Which differences actually matter?
Notation is not the difference worth chasing. A heading can use an HTML element in one version and a hash mark in the other and still say the same thing. The difference that matters is in the content itself.
HTML carries the structure a browser renders, often with navigation and controls around the main text. Markdown expresses text structure with lighter notation.
The problem starts when the content changes with the format. A condition disappears from a service description. A table keeps an old value. A link has the same label but points to another address.
These are examples of differences worth checking, not findings about anyone else's website. A client using Markdown receives the content in that response. If the response omits a condition, that condition is absent from the material the client was given, regardless of how clearly it appears in a browser.
Serving a Markdown response and keeping it consistent with the HTML are separate things to verify.
What does the checker compare?
It compares the main content of the two versions block by block. The checks cover headings and paragraphs, list items, tables, code blocks and links, and every reported difference points back to the text it came from.
I built markdown-parity-check for this comparison. It extracts the main content from HTML and lines it up with the Markdown.
Missing or added blocks are errors. Changed wording and changed numbers can fail the comparison too, and so can a link that keeps its label but points to a different address. Changes in heading level or order are reported as warnings, as are changes in case or punctuation.
A warning still needs reading. The order of instructions can matter even when the words match. The tool's severity is a starting point for review.
How do I run it on my own page?
With Node.js 22 or newer available, this command requests both representations of my tools page and prints the comparison:
npx --yes markdown-parity-check --url https://turva.dev/tools
It sends one request with the header Accept: text/html and another with Accept: text/markdown. Replace the address with your own public page. When Markdown lives at a separate address, supply it with --markdown-url. The usage documentation also covers comparing two local files.
In URL mode the delivery check runs first. An HTTP error or an HTML response in place of Markdown fails that check. The content comparison stops there.
For a build pipeline, --format json --output report.json writes a structured report, and --strict makes warnings reject the run too. Exit code 1 means the completed check found a rejecting difference. Exit code 2 means an input or execution problem prevented a reliable comparison. Both deserve attention, for different reasons.
Choose what you compare
The HTML container matters. By default, the tool looks for main, then article, then an element with role=main, and falls back to the page body. That fallback lets navigation and other surrounding content enter the comparison, and it produces a warning. Use --selector when the intended content needs a more precise boundary.
Markdown front matter is kept by default. If that metadata has no HTML counterpart, it can fail the comparison on its own. Use --front-matter strip when front matter is outside the content you intend to compare, and keep that choice visible in the command.
I would start with the page a buyer relies on to understand a service. Reading that report is what tells me which differences belong in the source. Then I would keep the same comparison in the release checks. A shorter report is useful only if it still covers the content that matters.
Can I run the check in a browser?
The browser version checks published pages on turva.dev. It refuses addresses on other sites. Use the command-line package for your own public site or a pair of local files.
The hosted page pins a release and applies smaller limits. Its report includes a toolVersion field, which matters when comparing results from the browser and the command line. The npm package can be newer than the hosted release.
JavaScript is not executed by the checker. It compares the HTML as received, so content added later in a browser needs a separate check. Block matching is heuristic too. A clean report means the implemented checks found nothing to reject. It does not prove that the two versions mean the same thing, or that either version is factually correct.
The Related section on my tools page is the kind of finding I want this to expose: a difference I can locate in both versions and decide about before the next release.
Frequently asked
Does a clean report mean the two versions say the same thing?
No. It means the implemented checks found nothing to reject in the blocks that were extracted. Block matching is heuristic, JavaScript is not executed, and nothing in the tool reads meaning. A plain diff would report every notation difference instead, which is why this comparison aligns blocks first.
Can I run it against a site I do not own?
Yes, from the command line. The package takes any public address with --url and compares what that address returns for Accept: text/html and for Accept: text/markdown. The hosted page on this site is the exception. It checks turva.dev pages only and answers 403 for any other host.
What should I fix first when the report is long?
The differences that change what a reader is told: a condition that is missing, a number that moved, a link whose target is not the one in the other version. I read the ordering and punctuation warnings too, but they rarely change a release. The tool reports quantities and does not decide which difference matters to your business.