MkDocs Markdown: Write and Publish Docs with MkDocs

September 11, 2026 · 10 min read

MkDocs Markdown: Write and Publish Docs with MkDocs

MkDocs is a Python static site generator that turns a folder of Markdown files and one mkdocs.yml into a documentation website. You install it with pip, write pages in Markdown, preview with mkdocs serve, and publish with mkdocs gh-deploy. This guide takes you from zero to a deployed site, explains how its Python-Markdown dialect differs from GitHub's, and answers the "is it abandoned" question with dates.

What Is MkDocs Used For?

It builds project documentation: API references, user guides, internal handbooks, and anything else that fits a sidebar of pages. It reads .md files from a docs folder, renders them with the Python-Markdown library, and writes a static site directory you can host anywhere, from GitHub Pages to an S3 bucket.

The appeal is the size of the setup. There's one config file, one command to preview, and one command to deploy. Compared with Sphinx, which defaults to reStructuredText and a heavier toolchain, this is the docs-as-code option most teams can adopt in an afternoon. If you're choosing between the two markup languages, our Markdown vs reStructuredText comparison covers that decision.

Most real-world sites also install the Material theme, which adds search, dark mode, tabs, and admonition styling. The two projects are separate, and the section on their status below explains the relationship.

Install MkDocs and Create a Project

The getting started guide is short, and so is the setup. Version 1.6.1 requires Python 3.8 or newer. We recommend installing Material at the same time, since it pulls the generator in as a dependency.

pip install mkdocs-material
mkdocs new my-docs
cd my-docs

mkdocs new creates two things: a mkdocs.yml config file and a docs folder holding index.md. Replace the generated config with this one, which enables the four extensions most sites end up wanting.

site_name: My Project Docs
site_url: https://example.github.io/my-docs/

theme:
  name: material

nav:
  - Home: index.md
  - Guide:
      - Install: guide/install.md
      - Usage: guide/usage.md

markdown_extensions:
  - admonition
  - toc:
      permalink: true
  - pymdownx.superfences
  - pymdownx.tabbed:
      alternate_style: true
  - pymdownx.tasklist:
      custom_checkbox: true

Then start the live preview.

mkdocs serve

The docs say the server runs at http://127.0.0.1:8000/ and reloads when you save a file. Keep it running in a second terminal while you write.

How Does MkDocs Markdown Differ from GitHub Markdown?

This is the part that trips up people arriving from README files. Pages render through Python-Markdown, which the writing guide describes as almost completely compliant with the original Markdown reference implementation. It is not CommonMark and not GitHub Flavored Markdown, so several GitHub habits need an extension.

Out of the box, the configuration reference says the build enables meta, toc, tables, and fenced_code. Everything else in the table below needs a line under markdown_extensions.

GitHub habitWorks by default?What to add
Pipe tablesYes (tables)Nothing
Fenced code blocksYes (fenced_code)pymdownx.superfences for nesting and Mermaid
Task lists - [ ]Nopymdownx.tasklist
Strikethrough ~~text~~Nopymdownx.tilde
GitHub alerts > [!NOTE]NoUse admonition syntax instead
Footnotes [^1]Nofootnotes
Heading anchorsYes (toc)permalink: true to show the link
Emoji shortcodes :tada:Nopymdownx.emoji
Nested listsNeeds four-space indentsNothing, just indent by four

The last row bites often. Python-Markdown wants nested list items indented by four spaces, and a two-space indent that works on GitHub renders as one flat list.

1. Install
    - pip install mkdocs-material
    - pip install mkdocs
2. Serve

Draft pages in the editor below, which renders GFM, and treat anything that looks right there but breaks in mkdocs serve as a missing extension or an indent problem. The demo mixes features from both columns of the table so you can see which ones need a config line.

Install guide

Requires Python 3.8+. Standard syntax like this renders the same in MkDocs.

  • Task lists need pymdownx.tasklist in mkdocs.yml
  • Tables and fenced code work by default
Command Purpose
mkdocs serve live preview on port 8000
mkdocs build write the site folder
mkdocs gh-deploy push to GitHub Pages

Strikethrough like this needs pymdownx.tilde in MkDocs.

74 words432 characters14 lines
Markdown

Admonitions, Tabs, and Code Features

Three extensions do most of the heavy lifting on a typical docs site, and their syntax isn't Markdown you'll have seen elsewhere.

Admonitions come from Python-Markdown's admonition extension. The syntax is three exclamation marks, a type, an optional quoted title, and a four-space-indented body.

!!! warning "Back up first"
    This command rewrites the gh-pages branch.
    Commit your work before running it.

The type becomes the CSS class and the default title, so !!! note renders a box titled Note. Material styles a dozen types out of the box. Python-Markdown lists the extension as in maintenance mode and points to PyMdown's Admonition block plugin (which uses a /// fence syntax) as the actively developed alternative, but the !!! form above still works and is what Material documents. Our Markdown callout guide compares this with the GitHub and Obsidian equivalents.

Content tabs come from pymdownx.tabbed. Each tab starts with three equals signs and a quoted title, and consecutive tabs form one group.

=== "pip"
    ```bash
    pip install mkdocs-material
    ```

=== "uv"
    ```bash
    uv add mkdocs-material
    ```

Nesting a fenced block inside a tab is exactly why pymdownx.superfences is in the config above; the default fenced_code extension can't handle a fence indented inside another block. SuperFences also adds Mermaid diagram support and code annotations. For the rest of the code-block features, including titles and line highlighting, see our Markdown code block guide.

Internal Links and Navigation in MkDocs

Link between pages using relative paths to the .md files, and the build rewrites them to the right HTML URLs at build time.

See the [install guide](guide/install.md) and the [license](../about/license.md#terms).

The writing guide warns that absolute paths are not officially supported: they work locally and then break on a server with a different base URL. Anchors come from the toc extension, which lowercases the heading text and replaces spaces and punctuation with dashes, so ## Quick Start becomes #quick-start.

A related setting, use_directory_urls, is true by default and turns guide/install.md into /guide/install/ instead of /guide/install.html. Leave it on for a hosted site; set it to false only if you need the docs to open from the file system without a server.

Sidebar order comes from the nav block in mkdocs.yml. Pages you leave out of nav still build, but they only appear if something links to them. For a long page, toc also generates the right-hand outline; our Markdown table of contents guide covers how that compares with hand-written TOCs.

Build and Deploy the Site

Two commands finish the job. mkdocs build writes the complete static site into a site folder, which you can upload to any host. mkdocs gh-deploy goes one step further for GitHub projects.

mkdocs build
mkdocs gh-deploy

The deployment docs explain that gh-deploy builds the docs, commits the output to the gh-pages branch with the ghp-import tool, and pushes it. Two warnings from the same page are worth repeating: you can't review the built site before it's pushed, and any untracked files in the repository get deployed too. Run mkdocs serve first, and commit or stash before deploying.

For hosts other than GitHub Pages, point your deploy step at the site folder. Netlify, Cloudflare Pages, and GitLab Pages all accept a static directory, and a CI job that runs pip install mkdocs-material followed by mkdocs build is the whole pipeline.

One limitation to plan for: there's no built-in versioning. If you need docs for v1 and v2 side by side, the mike tool that Material recommends manages multiple deployed versions on the same gh-pages branch.

Is MkDocs Abandoned? MkDocs vs Material vs Sphinx

These three questions come up on every MkDocs search, so here are answers with dates rather than opinions.

Is MkDocs abandoned? Not abandoned, but slow. The latest release is 1.6.1 from August 30, 2024, and the most recent commit on the main repository at the time of writing is from October 2025. It builds fine on current Python and has more than 22,000 GitHub stars. Bug fixes still land; new features mostly arrive through the extension and theme ecosystem instead.

What is the difference between Material and MkDocs? One is the build tool; Material is a theme that runs on top of it. Material ships far more often, with version 9.7.7 released on July 17, 2026 after five releases between February and March 2026. The 9.7.7 release notes also announce that Material is scheduled to reach end of life on November 5, 2026, with maintenance limited to critical bug fixes and security updates until then, and point new projects to its successor, Zensical. Most of what people picture as a typical docs site built this way (search, tabs, dark mode, social cards) is Material. You configure it with theme: name: material and nothing else changes.

Sphinx or MkDocs? Sphinx if you're documenting a Python API and want autodoc, cross-references, and reStructuredText. The Markdown option if you want a fast setup and files that also read well on GitHub. For the wider docs-as-code picture, including other generators, our Markdown for documentation guide is the parent post; this one stays on the one tool.

MkDocs FAQ

MkDocs gives you a documentation site from a folder of Markdown and a 20-line config, with Material adding the polish most teams want. Enable admonition, toc permalinks, superfences, and tabbed up front, remember the four-space indent rule, and use relative .md links so builds stay portable. Draft your pages in the editor to check the standard syntax before you layer on the MkDocs extensions.