Skip to content

Commit e4fc7e9

Browse files
committed
Updated blog post on MkDocs 2.0
1 parent 379be06 commit e4fc7e9

File tree

1 file changed

+58
-8
lines changed

1 file changed

+58
-8
lines changed

docs/blog/posts/mkdocs-2.0.md

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ slug: mkdocs-2.0
1616

1717
# What MkDocs 2.0 means for your documentation projects
1818

19-
Last update: March 27, 2026 – see [update log].
19+
Last update: April 13, 2026 – see [update log].
2020

2121
---
2222

@@ -36,6 +36,22 @@ _Please note that MkDocs 2.0 is still in pre-release, and the information in thi
3636

3737
<!-- more -->
3838

39+
---
40+
41+
__This is the fifth article in a series:__
42+
43+
1. [Transforming Material for MkDocs]
44+
2. [Zensical – A modern static site generator built by the creators of Material for MkDocs]
45+
3. [Material for MkDocs Insiders – Now free for everyone]
46+
4. [Goodbye, GitHub Discussions]
47+
5. [What MkDocs 2.0 means for your documentation projects]
48+
49+
[Transforming Material for MkDocs]: transforming-material-for-mkdocs.md
50+
[Zensical – A modern static site generator built by the creators of Material for MkDocs]: zensical.md
51+
[Material for MkDocs Insiders – Now free for everyone]: insiders-now-free-for-everyone.md
52+
[Goodbye, GitHub Discussions]: goodbye-github-discussions.md
53+
[What MkDocs 2.0 means for your documentation projects]: mkdocs-2.0.md
54+
3955
## What's changing in MkDocs 2.0
4056

4157
Based on the [official announcement], the published [roadmap], and several prior comments and statements from the project's maintainer, MkDocs 2.0 is intended as a ground-up rewrite of the project to reduce complexity – and it comes with some important trade-offs:
@@ -95,14 +111,40 @@ The moment we learned about these plans, [we immediately started working] on wha
95111

96112
For years, we were trying to improve MkDocs from within. We authored [12 plugins], which gave us a deep understanding of the plugin API's limitations. We conducted quantitative and qualitative analyses of the ecosystem to identify where MkDocs was falling short and talked to dozens of organizations and key ecosystem members. We raised these issues and repeatedly got nowhere. When the new direction of MkDocs 2.0 became apparent, the thinking was already done.
97113

98-
We considered forking MkDocs, but quickly realized it wasn't viable: every plugin in the ecosystem has a direct dependency on `mkdocs`, which means forking MkDocs would require forking every single one of its [300 plugins]__like moving an entire city at once__.[^1]
114+
## Why forking is impractical
115+
116+
We considered forking MkDocs, but quickly realized it wasn't viable: every plugin in the ecosystem has a direct dependency on `mkdocs`, which means forking MkDocs would require forking every single one of its [300 plugins]__like moving an entire city at once__.
117+
118+
!!! info "Why forking MkDocs isn't a viable path"
119+
120+
MkDocs is Open Source and permissively licensed, so forking it seems like the natural answer – it's exactly what Open Source is designed for. Take the codebase, fix what's broken, maintain it under a new name, and move forward. There are two reasons why we don't consider this a viable path forward for the ecosystem:
99121

100-
[^1]:
101-
Forking is technically feasible by interposing on all MkDocs imports at runtime using Python's import hook machinery (i.e., custom `sys.meta_path` finders/loaders or `importlib` wrappers). In this model, one effectively shadows MkDocs modules by resolving import requests to alternative implementations, or by proxying and patching objects during module initialization.
122+
**The dependency problem.** Every plugin in the MkDocs ecosystem has a direct dependency on the `mkdocs` package. A fork would need a different package name, which means every one of the [300+ plugins] in the ecosystem would also need to be forked and updated.
102123

103-
However, this approach fundamentally relies on strict API and behavioral compatibility with MkDocs' internal module graph. Because imports are resolved dynamically and cached after first load, any divergence in function signatures, class layouts, side effects, or import order can introduce subtle breakage. As a result, all internal APIs – not just the public surface – must be preserved with near-exact fidelity.
124+
You could work around this by intercepting Python's import system at runtime, making your fork silently pretend to be `mkdocs` – and some forks have done exactly that. But this only preserves the ecosystem on the surface. Plugins interact with MkDocs in two ways: through the official hook system, and by directly calling functions and accessing data structures that MkDocs exposes. Unlike many languages, Python has no concept of visibility – there is no distinction between public and internal APIs. In practice, this means that every function, class, and variable in MkDocs is potentially plugin surface. Plugins routinely reach into MkDocs internals – not because they're badly written, but because there was no other way to get the job done. Any meaningful change to the codebase risks breaking plugins in ways that are hard to predict and even harder to debug.
104125

105-
In practice, this reduces the "fork" to a thin layer of indirection rather than a true divergence. Core functionality cannot be meaningfully refactored or redesigned without violating the implicit contracts embedded throughout the codebase. Consequently, the deeper systemic and structural limitations of MkDocs 1.x remain effectively unchanged under this strategy.
126+
**The architecture problem.** Even a fork that solves the dependency problem inherits the deeper issues that have held MkDocs back for years. Anyone who has written MkDocs plugins knows the long tail of "plugin X is incompatible with plugin Y" reports – these aren't one-off bugs, they're a systemic consequence of how the plugin architecture works. As we documented in [ZAP 007], the underlying problem is that MkDocs has no model of data dependencies, which makes the following impossible without a ground-up rewrite:
127+
128+
- **Parallel builds** – plugins share mutable state at fixed
129+
synchronization points, making safe parallelization impossible even
130+
with free-threaded Python.
131+
- **Differential builds** – without knowing what each plugin reads and
132+
writes, there's no way to skip work that hasn't changed.
133+
- **Multi-project coordination** – MkDocs has no programmatic API for
134+
coordinating multiple builds, forcing fragile workarounds like
135+
cross-process manifests.
136+
- **Meaningful caching** – with no runtime-managed build graph, every
137+
plugin has to implement its own caching, and most don't.
138+
- **Fast live preview** – MkDocs must complete a full build before the
139+
preview server accepts connections, because navigation requires the
140+
entire site to be known upfront.
141+
142+
A fork inherits all of these insurmountable limitations. The only way to fix these problems is to rethink how plugins work at a fundamental level – at which point you're no longer forking MkDocs, you're building something new.
143+
144+
That's what we did.
145+
146+
[300+ plugins]: https://github.com/mkdocs/catalog?tab=readme-ov-file#contents
147+
[ZAP 007]: https://zensical.org/spark/proposals/zap-007-module-system/
106148

107149
With forking being impractical, we had to start from scratch.
108150

@@ -135,9 +177,15 @@ _If you have any questions, feel free to reach out to Kathi at hello@zensical.or
135177

136178
## Updates
137179

138-
- __March 27, 2026__: In [Talk Python To Me #542](https://talkpython.fm/episodes/show/542), Martin Donath shares the backstory of Zensical, and reflects on the lessons learned maintaining Material for MkDocs for almost a decade.
180+
### April 2026
139181

140-
- __March 22, 2026__: In _[The Slow Collapse of MkDocs]_, Florian Maas outlines the entire timeline of events starting in 2014 that eventually led to the fracturing of the MkDocs ecosystem.
182+
- __April 13, 2026__: We added a section on why forking MkDocs isn't a viable path forward for the ecosystem – an excerpt of [ZAP 007], which analyzes MkDocs' architectural limitations.
183+
184+
### March 2026
185+
186+
- __March 27, 2026__: In [Talk Python To Me #542](https://talkpython.fm/episodes/show/542), Martin Donath shares the backstory of Zensical, and reflects on the lessons learned maintaining Material for MkDocs for almost a decade.
187+
188+
- __March 22, 2026__: In [The Slow Collapse of MkDocs], Florian Maas outlines the entire timeline of events starting in 2014 that eventually led to the fracturing of the MkDocs ecosystem.
141189

142190
- __March 10, 2026__: We released 9.7.5, which limits the version range of MkDocs to `<2`. This ensures that your builds will continue to work, even if MkDocs 2.0 is released.
143191

@@ -152,6 +200,8 @@ _If you have any questions, feel free to reach out to Kathi at hello@zensical.or
152200

153201
- __March 3, 2026__: We added a paragraph on the new contribution model that MkDocs 2.0 is adopting, and the implications for users and contributors from our perspective.
154202

203+
### February 2026
204+
155205
- __February 27, 2026__: We added a note on the `NO_MKDOCS_2_WARNING` environment variable to disable the MkDocs 2.0 incompatibility warning in Material for MkDocs.
156206

157207
- __February 19, 2026__: The published MkDocs 2.0 roadmap was deleted. The link now points to an issue comment that contains a screenshot of the last available version of the roadmap.

0 commit comments

Comments
 (0)