Issue 45 – Markdown is Holding You Back • Buttondown

I’ve used many content formats over the years, and while I love Markdown, I run into its limitations daily when I work on larger documentation projects.

In this issue, you’ll look at Markdown and explore why it might not be the best fit for technical content, and what else might work instead.

Markdown is everywhere. It’s human-readable, approachable, and has just enough syntax to make docs look good in GitHub or a static site. That ease of use is why it’s become the default choice for developer documentation. I’m using Markdown right now to write this newsletter issue. I love it.

But Markdown’s biggest advantage is its biggest drawback: it doesn’t describe the content like other formats can.

Think about how your content gets consumed. Your content isn’t just for human readers. Machines use it too. Your content gets indexed by search engines, and parsed by LLMs, and those things parse the well-formed HTML your systems publish. Markdown’s basic syntax only emits a small subset of the available semantic tags HTML allows.

IDE integrations can use your docs, too. And AI agents rely on structure to answer developer questions. If you’re only feeding them plain-text Markdown documents to reduce the number of tokens you send, you’re not providing as much context as you could.

Worse, when you want to reuse your content or syndicate content into another system, you quickly find out that Markdown is more of the lowest common denominator than a source of truth, as not all Markdown flavors are the same.

There are other options you can use that give you more control. But first, let’s look deeper into why you should move away from Markdown for serious work.

Markdown is “implicit typing” for content

If you’re a developer, you know all about type systems in programming languages. Some languages use Implicit typing, in which the compiler or interpreter infers the data type from the value. These languages give you flexibility, but no guarantees. That’s why many developers prefer languages that use explicit typing, where you predefine data types when writing the code. In those languages, the compiler doesn’t just build your code; it guarantees specific rules are followed. That’s the main reason for the rise of TypeScript over JavaScript: compile-time guarantees.

Markdown is implicit typing. It lets you write quickly, but without constraints or guarantees. There’s no schema. No way to enforce consistency. A heading in one file might be a concept, in another it might be a step, and there’s no machine-readable distinction between the two.

To complicate things further, there are multiple flavors of Markdown, each with its own features and markup. Here are just a few:

You think you’re writing “Markdown,” but what works in one tool may not render in another. Some Markdown processors allow footnotes, Others ignore soft line breaks. And some even require different formatting for code blocks. Inconsistency makes Markdown a shaky foundation for anything beyond the most basic document.

And then there’s MDX, which people often use to extend Markdown to support things it doesn’t:

Here’s a typical MDX snippet:

# Install

npm install my-library

That tag isn’t Markdown at all; it’s a React component. Instead of using a code block, the author chose to create a special component to standardize how all commands would display in the documentation.

It works beautifully on their site because their publishing system knows what means. But if they try to syndicate this content to another system, it breaks because that system also needs to implement that component. And even if it was supported elsewhere, there’s no guarantee that the component is implemented the same way.

MDX shows that even in Markdown-centric ecosystems, people instinctively add more expressive markup. They know plain Markdown isn’t enough. They’re reinventing semantic markup, but in a way that’s custom, brittle, and not portable.

Why semantic markup matters

Semantic markup describes what content is, not just how it should look. It’s the difference between saying “here’s a bullet with some text” and “here’s a step in a procedure.” To a human, those may look the same on a page. To a machine or to a publishing pipeline, they are entirely different.

Web developers already went through all this with HTML. Prior to HTML5, you had

as a logical container. But HTML5 introduced

,

,