unsubbed.co

MkDocs

Static site generator for project documentation using Markdown files with themes and plugins.

Static site documentation, honestly reviewed. No marketing fluff, just what you get when you choose MkDocs over the alternatives.

TL;DR

  • What it is: Open-source (BSD-2-Clause) static site generator written in Python, purpose-built for project documentation. You write Markdown, configure one YAML file, and get a navigable documentation site [README].
  • Who it’s for: Developers, technical writers, and engineering teams who want to publish clean documentation without maintaining a CMS or paying for a hosted platform. Also relevant for solo builders who want to self-host their notes or internal wikis [1][2].
  • Cost savings: No SaaS equivalent to escape — MkDocs is the free alternative to paid documentation platforms like GitBook, Confluence, or Notion. A $5–10/mo VPS can host documentation for an unlimited number of projects [2].
  • Key strength: Minimal setup path from Markdown files to a working site. The Material for MkDocs theme (a separate project by Martin Donath) adds full-text search, responsive layout, versioning, and admonitions that the base themes don’t provide [4].
  • Key weakness: The base MkDocs themes are dated. Without the Material theme, the output looks like documentation from 2015. The plugin ecosystem is powerful but fragmented — you’ll assemble the right combination yourself, and documentation quality varies significantly across plugins [4].

What is MkDocs

MkDocs is a static site generator written in Python, specifically intended for project documentation. You write your content in Markdown files, configure the site structure in a single mkdocs.yml file, run mkdocs build, and get a folder of static HTML that you can serve from GitHub Pages, S3, Apache, Nginx, or a Raspberry Pi on your local network [README][2].

The project was originally created by Tom Christie, who is also known for creating Django REST Framework [4]. It sits at 21,862 GitHub stars under a permissive BSD-2-Clause license, which means you can use it in commercial products, embed it in internal tooling, or ship it as part of a client deliverable without negotiating anything [README].

The pitch is simple and accurate: “Project documentation with Markdown.” There is no subscription, no vendor lock-in, no per-seat pricing. Your documentation is a folder of text files under version control, built by a Python package.

What separates MkDocs from “just writing Markdown and pushing to GitHub” is the navigation, search, theming, and plugin system. A bare GitHub repository renders your Markdown, but gives you no sidebar, no search, no versioning, and no consistent layout. MkDocs gives you all of that, configurable, without writing HTML [4].


Why People Choose It

The recurring pattern across the articles reviewed is that people land on MkDocs after rejecting alternatives for different reasons.

From the developer comparison angle [4]: A developer building an iOS app tried GitHub Pages (too limited — no search, no sidebar navigation, no admonitions), Docsify (no build step but poor SEO and performance at scale), Docusaurus (too heavy for solo projects, React dependency, overkill unless you’re a large OSS project), and GitBook (hosted, not self-owned). MkDocs with the Material theme was the conclusion: enough structure to be serious, light enough to not require a full Node.js ecosystem, open source with no lock-in.

From the Obsidian self-hosting angle [1]: A user who wanted to replace Obsidian Publish (a paid service at $8/mo) with a self-hosted alternative built on top of MkDocs. The appeal was that MkDocs can be extended with custom plugins for wikilinks, backlinks, callouts, and a blogging layer — things Obsidian Publish offers natively but locks behind their platform. The trade-off cited honestly: “Installation and configuration is for a person who is not afraid of some manual work and has basic Python knowledge.” Not a tool for non-technical users without help.

From the enterprise docs-as-code angle [3]: Siemens uses MkDocs internally, combined with the Material theme and GitLab CI/CD, for technical documentation at scale. The MR review workflow they describe — using GitLab job artifacts and review apps to deploy preview versions of docs for each merge request — is a pattern that wouldn’t be possible with a hosted documentation SaaS. The static-output model is what enables it: because the build output is just files, you can deploy a hundred simultaneous preview environments without any special infrastructure [3].

From the AWS docs-as-code angle [5]: MkDocs is positioned as one of two serious Python-based options (alongside Sphinx) for teams that want to connect documentation to a database, automate deployment through GitHub Actions, and host on cloud infrastructure. The article compares MkDocs and Docusaurus for this purpose — Docusaurus wins on React ecosystem integration, MkDocs wins on Python ecosystem fit and simpler configuration [5].

The common thread: people choose MkDocs when they want documentation that behaves like code — versioned, CI/CD deployable, hosted on infrastructure they control, not billed monthly by a vendor.


Features

Based on the README, website, and article coverage:

Core documentation engine:

  • Converts Markdown files to static HTML [README]
  • Single mkdocs.yml configuration file controls the entire site [README]
  • Built-in dev server with live reload — changes in your editor appear in the browser immediately [website]
  • Two built-in themes: mkdocs (default, basic) and readthedocs (mimics the Read the Docs platform) [website]
  • Deploys to GitHub Pages, Amazon S3, Netlify, or any static hosting — mkdocs gh-deploy handles GitHub Pages in one command [README]
  • Supports relative URL paths — the same build can be served from any path prefix without reconfiguration [3]
  • Two URL styles: directory URLs (default, /page/) or file URLs (/page.html) configurable via CLI flags [3]

Plugin and extension system:

  • Plugin API for extending build behavior — used for search, minification, PDF export, blog support, and more [README][website]
  • Markdown Extensions support via Python-Markdown — add admonitions, code highlighting, tables of contents, footnotes, and custom syntax [4][website]
  • Third-party plugin and theme catalog maintained at github.com/mkdocs/catalog [README]

Material for MkDocs (third-party theme, commonly used together):

  • Full-text search [4]
  • Responsive layout [4]
  • Versioning support [4]
  • Keyboard navigation [4]
  • Admonitions, tabs, and diagrams [4]
  • Maintained independently by Martin Donath, not by the MkDocs core team [4]

Self-hosting specifics:

  • mkdocs build outputs a site/ folder of static files [2]
  • Can be served with Apache, Nginx, Caddy, or any static file server [2]
  • Runs on low-powered hardware — a Raspberry Pi is sufficient for a local-network deployment [2]
  • Works inside GitLab CI/CD for merge request preview deployments with no extra infrastructure [3]
  • Integrates with AWS S3, Terraform, and GitHub Actions for cloud deployments [5]

Pricing: SaaS vs Self-Hosted Math

MkDocs itself is free. There is no SaaS tier, no hosted version sold by the MkDocs project, and no commercial license to buy.

The relevant cost comparison is against paid documentation platforms:

GitBook: Free for public/open source projects. Paid plans start at $6.70/user/month (billed annually). A 5-person team runs $33/mo. At 20 people, $134/mo.

Confluence: Atlassian’s documentation product. Free for up to 10 users, $5.75/user/month after that. At 20 users, $115/mo.

Notion (used for docs): Free for individuals. Teams plan at $10/user/month. At 20 users, $200/mo.

MkDocs self-hosted: $0 for the software. A VPS to host the built output: $5–10/month on Hetzner, DigitalOcean, or Contabo. If you’re deploying to GitHub Pages, S3, or Netlify’s free tier, your hosting cost is $0.

For a 10-person engineering team paying GitBook’s team plan, the annual cost is roughly $800–$1,600. Self-hosted MkDocs with a small VPS runs ~$60/year and serves unlimited users and projects. The math is straightforward.

The meaningful cost here isn’t money — it’s time. Someone has to set up the build pipeline, maintain the Python environment, and handle upgrades. For a team that already has CI/CD infrastructure, this is negligible overhead. For a team that doesn’t, factor in a few hours upfront.


Deployment Reality Check

MkDocs deployment is simpler than most self-hosted tools because the output is static files. There’s no database, no application server to keep running, no memory leak to restart.

Minimal path (local network, Raspberry Pi) [2]:

  1. Install MkDocs via pip: pip install mkdocs
  2. Write Markdown files and configure mkdocs.yml
  3. Run mkdocs build — this generates a site/ folder
  4. Move the site/ folder to your web server directory (e.g., /var/www/html on Apache2)
  5. Access the site on your local network

The Reddit user who documented this process noted it took a bit of iteration to understand that mkdocs serve (the dev server) binds to 127.0.0.1 by default and isn’t accessible from other machines on the network — you need to either bind it to 0.0.0.0 or use mkdocs build + a proper web server for network access [2].

CI/CD path (GitLab, enterprise) [3]: Siemens runs MkDocs through GitLab CI. Each merge request gets a preview deployment using GitLab job artifacts served as GitLab Pages. The key configuration detail: because GitLab artifacts don’t serve directory URLs the same way Pages does, you need to build with --no-directory-urls to generate explicit .html file paths. This is a genuine gotcha that isn’t in the basic documentation and took engineering effort to figure out [3].

Cloud path (AWS with Terraform + GitHub Actions) [5]: For teams that want fully automated documentation pipelines connected to live data sources, the build process involves more infrastructure: S3 for hosting, CloudFront for CDN, Terraform for provisioning, and GitHub Actions for triggering builds on commit. This is well-documented territory, but it’s genuinely more infrastructure than a static site traditionally requires.

Python environment considerations: MkDocs is a Python package. You need Python installed (Python 3.x). If your project already uses Python, this is zero additional overhead. If you’re a JavaScript shop, adding a Python environment to your CI/CD pipeline is an extra step. It won’t break anything, but it’s not invisible.

Material theme installation: The base MkDocs themes look like documentation from 2014. The Material theme (pip install mkdocs-material) is practically required for a modern-looking result and is what appears in the majority of MkDocs deployments. It’s free and open source, but it’s a separate install from a different maintainer — something to understand before assuming MkDocs ships looking like the polished examples you see online [4].


Pros and Cons

Pros

  • BSD-2-Clause license. Use it in commercial products, client work, internal tooling — no restrictions [README].
  • Static output. No runtime, no database, no server to maintain. Deploy anywhere that serves files. Scale to zero. Survives a VPS reboot without attention [2][5].
  • Docs-as-code workflow. Documentation lives in version control alongside the code it describes. Review documentation changes in pull requests. Roll back to previous states. Enforce documentation updates in CI [3][5].
  • Live dev server. Edit Markdown, save, browser updates automatically. The feedback loop for writing documentation is as fast as it is for code [website].
  • Extensible plugin system. Search, PDF export, blog support, git integration, redirect handling — if you need it, there’s likely a plugin [README][1].
  • Self-hostable on minimal hardware. A Raspberry Pi on a local network is sufficient for a private internal documentation site [2].
  • Enterprise-proven. Siemens runs it internally at scale with GitLab CI/CD and merge request preview workflows [3].

Cons

  • Base themes are poor. mkdocs and readthedocs themes look dated. The Material theme is effectively required for a modern result, but it’s a separate third-party project with its own release cadence and maintainer [4].
  • Python dependency. Adds Python to your environment if you don’t already have it. Minor for Python teams, noticeable for JavaScript or Go shops [5].
  • Not beginner-friendly without help. A forum post about self-hosting MkDocs for Obsidian notes explicitly warns that setup “is for a person who is not afraid of some manual work and has basic Python knowledge” and recommends the official paid Obsidian Publish service if that’s a barrier [1].
  • No dynamic features. Search is client-side JavaScript. No authentication, no user accounts, no comments, no gating. If you need any of that, it’s on you to add it [website].
  • Plugin fragmentation. The third-party plugin ecosystem is large but uneven. Plugin documentation quality varies significantly, and finding the right combination of plugins for a specific feature (like blogging or PDF export) requires trial and error [1].
  • No built-in versioning. The core MkDocs package doesn’t handle documentation versioning across software releases. You need mike (a third-party tool) for that, which the Material theme integrates with but MkDocs itself doesn’t ship [4].
  • CI/CD edge cases require expertise. The GitLab review app workflow at Siemens required specific flag configuration (--no-directory-urls) and understanding of how job artifacts serve files differently from GitLab Pages — not documented clearly in official sources [3].

Who Should Use This / Who Shouldn’t

Use MkDocs if:

  • You’re a developer or technical writer who wants documentation that lives in the same repository as the code.
  • Your team already uses Python or is comfortable adding it to the environment.
  • You want to deploy to GitHub Pages, S3, or a VPS for free or near-free.
  • You need CI/CD-integrated documentation previews in pull requests and merge requests.
  • You’re replacing a paid documentation platform (GitBook, Confluence) for a small team and want to stop paying per seat.

Skip it (stick with GitBook or Notion) if:

  • You’re non-technical and need to write and publish documentation without touching a terminal or understanding a build process.
  • Your team doesn’t want to own any infrastructure at all, even a static hosting bucket.
  • You need WYSIWYG editing — MkDocs requires writing raw Markdown.

Skip it (use Docusaurus instead) if:

  • Your team is React-native and wants to extend documentation with custom React components.
  • You’re building a large OSS documentation site with complex versioning needs and a developer community contributing to it.

Skip it (use Sphinx instead) if:

  • You’re building Python library documentation that needs to pull from docstrings automatically.
  • Your project already uses the Python docs ecosystem (ReadTheDocs hosting, autodoc).

Alternatives Worth Considering

  • Docusaurus — React-based SSG, better for large OSS projects with complex versioning, heavier setup, requires Node.js [4][5].
  • Sphinx — the original Python documentation tool, built for API references and docstring extraction. MkDocs is simpler; Sphinx is more powerful for library documentation.
  • GitBook — hosted, WYSIWYG, no command line required. Free tier is limited; paid plans start around $6.70/user/month. The non-technical founder’s choice if budget allows.
  • Docsify — no build step, renders Markdown in the browser at runtime. Easier to start, weaker SEO, worse performance at scale [4].
  • Jekyll — the original GitHub Pages SSG. More general-purpose, Ruby-based, not documentation-focused.
  • Hugo — fastest static site generator available, Go-based, general-purpose. Powerful but requires more configuration work than MkDocs for documentation specifically.

For a developer who just wants documentation running on GitHub Pages or a VPS with minimal setup, the realistic shortlist is MkDocs vs Docusaurus. MkDocs if you prefer Python and simplicity. Docusaurus if you prefer JavaScript and flexibility.


Bottom Line

MkDocs does exactly what it claims: converts Markdown files into clean documentation sites with minimal configuration. The BSD-2-Clause license, static output, and zero hosting costs make it a straightforward choice for any developer or engineering team that wants to escape per-seat documentation pricing. The caveats are real — the base themes are inadequate (Material theme is the practical default), it requires Python, and non-technical users will need help with setup. But for the target audience — engineers who want documentation that behaves like code, version-controlled and CI/CD deployable — those caveats are minor. Twenty-one thousand GitHub stars and adoption inside companies like Siemens suggest the tool earns its reputation through reliability, not marketing.

If the setup is the blocker, that’s exactly what upready.dev handles for teams — one-time deployment, you own the infrastructure and the documentation forever.


Sources

  1. maQ — “Self hosted notes by using MkDocs (with blogging capability)” — Obsidian Forum Share & Showcase (Jun 2023). https://forum.obsidian.md/t/self-hosted-notes-by-using-mkdocs-with-blogging-capability/61643
  2. sowhatidoit — “Is it possible to self host MKDocs?” — Reddit r/selfhosted. https://www.reddit.com/r/selfhosted/comments/16eq3fj/is_it_possible_to_self_host_mkdocs/
  3. Sigurd Spieckermann — “Visual review of MkDocs sites in GitLab MRs” — Siemens Blog (Nov 2, 2023). https://blog.siemens.com/2023/11/visual-review-of-mkdocs-sites-in-gitlab-mrs/
  4. thepassionatecoder.com — “Choosing a Documentation Tool” — thepassionatecoder.com. https://www.thepassionatecoder.com/post/building-in-public-choosing-a-documentation-tool
  5. Romina Elena Mendez Escobar — “Deploying Docs-as-Code on AWS: Building Dynamic Documentation Sites in MkDocs and Docusaurus” — Medium (Nov 20, 2024). https://medium.com/@romina.elena.mendez.escobar/deploying-docs-as-code-on-aws-building-dynamic-documentation-sites-in-mkdocs-and-docusaurus-648538d61573

Primary sources:

Features

Integrations & APIs

  • Plugin / Extension System

Customization & Branding

  • Themes / Skins