Original Markdown
Changed Markdown

Markdown Diff: Compare Two Markdown Files Online

Paste two Markdown documents and see what changed line by line. Works on README files, release notes, MDX, and frontmatter-tagged docs. The diff runs in your browser.

What is the Markdown diff tool?

A free, in-browser tool for comparing two Markdown documents at the source-text level. Paste an old README.md on the left, the updated one on the right, and every changed heading, list item, link, code block, and table cell lights up. Nothing leaves your machine.

The diff runs character by character. Markdown is plain text, so this is the right primitive: you see the literal change in the document source, not a guess at how a renderer would interpret it.

If you already use our text diff for general prose, the Markdown page is the same engine with copy aimed at the cases that come up when you actually write docs. For comparing the YAML frontmatter blocks at the top of Jekyll, Hugo, or MkDocs files, the YAML page handles the indent-sensitive structure better. Strict structured data with key/value lookups belongs in JSON diff.

How the diff actually works

The diff is character-level. After the raw diff, a semantic cleanup pass shifts the highlights so they land on whole words, list items, and link targets rather than splitting in the middle of an inline `code span` or breaking the leading ## off a heading. Insertions paint green on the right, deletions red on the left.

It is a source-text diff, not a rendered-output diff. That is the right primitive for Markdown work, and it matters more than it sounds. Two documents that render to identical HTML can have very different sources: **bold** versus __bold__, * bullets versus - bullets, four-space indents versus a tab on a nested list. A renderer flattens those into the same output and you would lose the signal. When you want to know whether a contributor really only fixed a typo, the source diff is what answers the question.

Markdown is also a family of dialects. The original spec by John Gruber (see daringfireball.net) was deliberately loose, and over time CommonMark, GitHub Flavored Markdown, Pandoc, and MultiMarkdown each pulled in a different direction. Tables exist in GFM and Pandoc but not in CommonMark. Strikethrough with ~~ and task lists with - [ ] are GFM extensions. The diff tool does not care which dialect you use; it shows the raw text. The flavour matters when you start asking whether a paragraph still renders correctly under the new docs theme, which is a question for your renderer, not the diff.

How to compare Markdown in three steps

Two text panes, one diff. No signup, no upload, no server round-trip.

  1. 1

    Paste or upload your Markdown

    Paste the old version on the left, the new version on the right. Or click Upload on either pane to load a .md, .markdown, or .mdx file. The Sample button fills both sides with a small README example so you can see the diff working before you paste your own content.

  2. 2

    Normalise line endings if needed

    A file edited on Windows usually has CRLF line endings; a file from a Linux server has LF. A character diff treats those as different, which can paint every line as changed. If the diff looks suspiciously full of red and green, normalise both files to the same line ending in your editor first. VS Code shows the active ending in the bottom status bar.

  3. 3

    Read the diff

    Deletions show red on the left, insertions show green on the right. The two panes scroll in lockstep. Frontmatter blocks, code fences, table rows, and list items are all just text to the diff engine, so changes inside them surface the same way as changes to body prose. The change counts in each header give you a quick gauge of how heavy the edit was.

When Markdown diff is the right tool

Reviewing README changes between PR branches

You want a fast read on what changed in README.md on a PR branch versus main, but you do not want to open GitHub, scroll past the rendered preview, and click "Display the source diff" three menus deep. Paste the two raw files into this tool instead. Headings, code fences, and link targets all surface clearly. Useful when the PR also touches a hundred source files and the docs change is hidden in the noise.

Comparing release notes V1 to V2 before publishing

Release notes go through several edits before they ship. Drafts get reordered, bullets get merged, version numbers shift around. Diffing the previous published RELEASE_NOTES.md against the new draft catches dropped entries and accidental duplicates, which the rendered preview is bad at because the eye glides over similar-looking lines. The diff also makes it easy to verify that the ## Breaking changes section actually grew between releases.

Diffing CMS export against the source repo

Your team writes docs in Markdown in a Git repo, but the public site is generated by a CMS or static-site generator like MkDocs, Hugo, or Docusaurus. Occasionally the published page drifts from the source: someone edited the live page through the CMS UI and forgot to push back, or a CI step rewrote the file. Export the published page as Markdown, drop it into one pane, drop the repo's .md into the other, and the drift is in front of you in seconds.

Blog post draft vs editor revisions

You sent a blog post to an editor in Markdown. The editor sent back a marked-up version. A diff between the two is a much faster way to absorb the feedback than rereading paragraph by paragraph, especially when the editor reordered sections or rewrote your intro. Works equally well for ghost-written content where the writer needs to confirm which voice tweaks survived the editing pass.

Auditing a Markdown to MDX migration

Migrating a Docusaurus or Astro site from .md to .mdx sounds like a no-op until you find that some imports moved, some JSX components replaced what used to be plain Markdown tables, and a few code fences are now wrapped in custom components. Diff the old page.md against the new page.mdx file by file and the migration choices become reviewable. Same workflow in reverse if you decide MDX was a mistake and you want to fall back to plain Markdown.

Markdown quick reference

A short cheat sheet for the syntax edge cases this tool surfaces most often. The dialect column tells you which flavours actually support the feature, since this is where most cross-renderer surprises come from.

TopicWhat this tool does
Flavour driftMarkdown is a family. CommonMark is the de-facto baseline. GFM adds tables, task lists, strikethrough, and autolinks. Pandoc and MultiMarkdown add footnotes, definition lists, and more. Same source can render very differently across them.
TablesPipe-delimited tables exist in GFM and Pandoc. They are not part of CommonMark or original Markdown. If a renderer prints raw | characters instead of cells, the parser is CommonMark-strict and you need a GFM-compatible one.
Strikethrough~~text~~ is a GFM extension. Original Markdown and CommonMark do not support it. Pandoc supports it with the strikeout extension enabled. If your text is rendering with literal tildes, the renderer is not GFM-aware.
Task lists- [ ] todo and - [x] done are a GFM extension. CommonMark renders them as plain bullets with literal brackets. GitHub, GitLab, and most modern docs sites support them; vanilla Markdown processors generally do not.
Code blocks: fenced vs indentedFenced code blocks (triple backticks or tildes, with optional language tag) are CommonMark and universally supported. The original Markdown spec only had four-space-indent code blocks, which still work but cannot carry a language hint. Mixing the two in one file is legal but messy.
Hard line breaksThree options: end a line with two trailing spaces, end a line with a backslash \ (CommonMark and GFM, not original), or insert a blank line for a paragraph break. Trailing spaces are invisible in most editors, which is why hard breaks frequently survive a diff that no human spots.
FrontmatterYAML between --- fences, TOML between +++, or JSON between { } at the very top of the file. Not part of the Markdown spec at all but ubiquitous in Jekyll, Hugo, MkDocs, Docusaurus, and Astro. Renderers strip it before parsing the body.
Inline HTMLCommonMark allows raw HTML tags inside Markdown. GFM does too but applies an HTML sanitiser when rendering on github.com. Some static-site generators sanitise, some pass HTML through, and a few escape it. Diffs of pages with embedded <div> or <iframe> blocks are common in migration audits.

Markdown diff: frequently asked questions

Does this preview the rendered output?

No. The tool diffs the Markdown source text, not the HTML a renderer would produce. That is intentional. Two documents can render to identical HTML and still have meaningfully different sources, for example bullets written with * versus - or bold written with ** versus __. Source-level diff preserves that signal. If you want to see how the document renders, paste it into your usual previewer like the GitHub web UI, VS Code, or your static-site generator.

How is this different from comparing rendered HTML?

A rendered-HTML diff tells you what readers will see. A source diff tells you what was actually changed in the file. They answer different questions. For Markdown, the source diff is almost always the more useful one because it shows the writer's edits faithfully: a heading level changed from ## to ###, a fenced code block switched language tags, a relative link became absolute. If you want HTML-level comparison, run both files through your renderer first and diff the output.

What about CommonMark vs GitHub Flavored Markdown ambiguity?

The diff itself does not parse Markdown, so it does not care which dialect you use. Tables, task lists, strikethrough, and autolink extensions all just look like text. The flavour matters when you ask whether your document still renders correctly. CommonMark is the closest thing to a baseline spec, and GitHub Flavored Markdown is CommonMark plus tables, task lists, strikethrough, and autolinks. Pick whichever your target renderer supports.

How does it handle YAML or TOML frontmatter?

Frontmatter is just text at the top of the file, fenced by --- for YAML or +++ for TOML. Static-site generators like Hugo, Jekyll, and MkDocs use it for page metadata. The diff treats the block as ordinary text, so changes to title:, date:, or tags: show up like any other line. If your frontmatter is large and indent-sensitive, our YAML diff page is the better pick for that block in isolation.

Does it work for MDX or JSX inside Markdown?

Yes. MDX is Markdown with embedded JSX components, and the JSX is just more text from the diff's point of view. You can paste a .mdx file in either pane and the diff will surface changes to imports, component props, and the surrounding Markdown the same way it handles .md. The only thing the tool will not do is validate that your JSX compiles; that is the MDX compiler's job. For straight code review of the JSX bits, paste them into our text diff.

How are line endings (CRLF vs LF) handled?

Line endings are characters, so a file saved with Windows-style CRLF and a file saved with Unix-style LF will diff as different at every line. If your panes look full of phantom changes, this is almost always the cause. The fix is to normalise both files to the same line ending in your editor before pasting; in VS Code the active ending is shown in the bottom status bar and is one click to switch. Git's core.autocrlf setting can also introduce surprise CRLF differences between machines.

Does the diff care about CommonMark vs GFM or MDX differences?

It is a text diff, so any character-level change shows up regardless of dialect. CommonMark is the strict spec; GitHub Flavored Markdown adds tables, task lists, strikethrough, and autolinks; MDX adds JSX inside Markdown bodies. A renderer that normalises **bold** to __bold__ (some Pandoc filters do this) produces text-diff noise even though the HTML output is identical. If you want semantic equivalence, render both sides through the same renderer and diff the output with our HTML diff page.

How does the diff handle YAML or TOML frontmatter at the top of the file?

Frontmatter is the metadata block at the top, between --- lines for YAML (Hugo, Jekyll, Astro), +++ for TOML (Hugo TOML mode), or ;;; in some setups. The text diff sees frontmatter and body as one stream, so a date update or tag reorder shows up alongside body changes. For SEO-significant fields like title, description, or slug, that is good. For volatile fields (updated_at, build hashes), strip them before diffing. Hugo and Jekyll _config.yml define which fields rotate per build.

Privacy and how this works

Your Markdown never leaves your browser. The editor, the diff, and the formatter all run on your machine. No analytics on your input, no logs, no server round-trip. Background reading on the format itself sits at Wikipedia, with the latest CommonMark spec at spec.commonmark.org/0.31.2 and the GitHub flavour at github.github.com/gfm.