Skip to main content

Command Palette

Search for a command to run...

we dropped Docusaurus adapter

Updated
4 min read

We Built a Docusaurus Adapter for Our Documentation Linter. Then We Deleted It.

We spent a full development cycle building support for Docusaurus in Zenzic.

Zenzic is a static documentation linter that validates links, structure, and integrity of documentation sources before they reach production.

The Docusaurus adapter was supposed to extend compatibility.

Instead, it revealed a deeper problem: some documentation systems are not statically analyzable in a meaningful way.

So we deleted it.

This is why.


What we were trying to do

Zenzic works by parsing documentation source files and building a complete map of:

  • pages

  • internal links

  • anchors

  • references

It assumes a key constraint:

«documentation structure is derivable from source without executing runtime code»

Most static site generators fit this model.

Docusaurus does not.


The assumption we got wrong

We initially believed Docusaurus would be mostly:

  • Markdown files

  • predictable slugs

  • deterministic anchor generation

We were wrong.

In practice, Docusaurus behaves like a React application that uses Markdown as an input format.

That distinction matters.


What broke static analysis

During testing against real Docusaurus projects (including its own documentation), we found structural issues that could not be resolved statically.

  1. Runtime-generated anchors

Some anchors are not derived from Markdown at all.

They are injected by React components at render time.

Example: API tables generate HTML IDs directly from JavaScript objects, preserving casing and punctuation that never exists in source Markdown.

From a static analyzer perspective, these anchors do not exist.


  1. MDX partial merging

Docusaurus allows content to be split into multiple MDX files and recombined at build time.

This means:

  • a heading in file A

  • can become an anchor in file B

  • after a bundler step

Static file analysis cannot reconstruct this without reimplementing the MDX pipeline.


  1. Render-time truth vs source truth

We discovered a consistent pattern:

  • source files are incomplete representations of final documentation

  • the final DOM is the authoritative model

Zenzic operates on source files.

Docusaurus final state is only visible after a full React + bundler execution.


The key problem: mismatch of models

At this point, the issue was no longer about missing features.

It was about incompatible assumptions:

  • Zenzic: documentation is a static graph

  • Docusaurus: documentation is a runtime-rendered application

These are not two implementations of the same idea.

They are different models of what documentation is.


Why we deleted the adapter

We briefly considered shipping it with limitations:

  • “React-generated anchors not supported”

  • “MDX partial resolution not guaranteed”

But this created a worse problem.

Most users would hit those limitations immediately.

And worse: they are not edge cases in Docusaurus.

They are core features.

In practice, the adapter would have produced:

  • false positives

  • inconsistent reports

  • broken trust in CI results

A documentation quality gate that produces unreliable signals is worse than no tool at all.

So we removed it.


What we learned

The mistake was not technical.

It was architectural.

Static analysis tools assume:

«the system they analyze has a stable representation at rest»

Some systems do not have that property.

When a documentation system requires runtime execution to define its structure, it stops being a static artifact.

It becomes a program that generates documentation.

And programs are not safely analyzable without executing them.


What Zenzic supports instead

We decided to support only systems where structure is deterministic from source files:

  • MkDocs

  • Sphinx

  • Hugo

  • Jekyll

  • controlled Markdown pipelines

These systems expose a stable mapping between:

source → structure → output

That stability is what makes static validation possible.


Closing thought

This was not a failure of implementation.

It was a boundary discovery.

Some systems are not compatible with static verification by design.

Recognizing that boundary early is more important than forcing compatibility.


Source: https://zenzic.dev

13 views