Documentation as Code

Documentation as Code (Docs as Code) is the practice of treating documentation with the same rigor, tooling, and workflows as software source code. Instead of documentation living in a wiki, a Google Doc, or a separate content management system, it lives in the same repository as the code it describes. It is written in plain text markup, version-controlled with Git, reviewed through pull requests, tested in CI, and deployed automatically. This approach fundamentally changes the quality and reliability of documentation because it becomes a first-class citizen in your development workflow.

Docs Living Alongside Code in the Repository

The single most impactful decision you can make for documentation quality is to store your docs in the same repository as your code. When documentation lives in a separate system — a Confluence space, a shared drive, a standalone wiki — it inevitably drifts out of sync with the code. Developers change the code but forget to update the external documentation because it requires switching tools, navigating to a different system, and editing in a different format.

When docs live in the repository:

  • Changes are atomic: A pull request can update both the code and its documentation in a single commit. Reviewers can verify that the docs accurately reflect the code changes.
  • History is shared: Git blame and log work on documentation files just as they do on code files. You can trace when a section was added, who wrote it, and why.
  • Access is automatic: Anyone who has access to the code also has access to the docs. There is no separate permissions system to manage.
  • Branching works naturally: Feature branches can include documentation for the new feature. When the branch is merged, the docs go live with the code.
  • Reviews catch documentation issues: Code reviewers naturally review the accompanying documentation changes, catching errors, omissions, and unclear explanations before they reach users.

The typical structure is a docs/ directory at the root of your repository. Some projects use documentation/, doc/, or keep docs alongside the code files they describe (e.g., src/auth/README.md documenting the auth module). The specific structure matters less than the principle: docs and code live together and evolve together.

Markdown as the Lingua Franca

Markdown has become the universal standard for documentation in software projects. It is lightweight, readable in its raw form, supported by every major code hosting platform, and convertible to virtually any output format (HTML, PDF, EPUB, slides). GitHub, GitLab, and Bitbucket all render Markdown automatically, which means your documentation looks good without any build step.

Key advantages of Markdown for documentation:

  • Low barrier to entry: Markdown syntax is intuitive. Developers can start writing documentation immediately without learning a complex markup language.
  • Diff-friendly: Because Markdown is plain text, Git diffs show exactly what changed in a documentation update. Reviewers can see additions, deletions, and modifications clearly.
  • Tool ecosystem: Hundreds of tools understand Markdown — editors with live preview, linters, formatters, static site generators, and conversion tools.
  • Portable: Markdown files can be moved between systems, converted to other formats, and processed by different tools without vendor lock-in.

Some projects use reStructuredText (rST) instead of Markdown, particularly in the Python ecosystem where Sphinx is the dominant documentation tool. Others use AsciiDoc for its richer feature set. But for most projects, Markdown's simplicity and ubiquity make it the best default choice.

Static Site Generators for Documentation

While Markdown files in a repository are a great starting point, most projects eventually need a polished documentation website with navigation, search, versioning, and custom branding. Static site generators transform your Markdown files into a professional documentation site that can be hosted cheaply (or free) on platforms like GitHub Pages, Netlify, or Vercel.

Docusaurus (React-based)

Docusaurus is a documentation-focused static site generator built by Meta (formerly Facebook) using React. It is the tool of choice for many large open-source projects including React Native, Jest, and Prettier. Docusaurus provides built-in support for documentation versioning, blog functionality, internationalization (i18n), and a powerful plugin system.

Key features of Docusaurus:

  • MDX support — embed React components directly in your Markdown files for interactive examples, tabs, and custom widgets
  • Automatic sidebar generation from your file structure
  • Built-in documentation versioning with a version dropdown
  • Full-text search integration (Algolia DocSearch or local search)
  • Dark mode support out of the box
  • Customizable with React components and CSS modules

Docusaurus is ideal for projects that need interactive documentation elements, have a React-savvy team, or want a modern documentation site with minimal configuration.

MkDocs (Python-based, Material theme)

MkDocs is a fast, simple static site generator designed specifically for project documentation. It is Python-based and configured with a single mkdocs.yml file. The Material for MkDocs theme has become so popular that it is the de facto standard for MkDocs-based documentation sites.

Material for MkDocs offers:

  • A beautiful, responsive design with dark mode
  • Built-in search that works offline
  • Code block syntax highlighting with copy buttons
  • Admonitions (note, warning, tip boxes) with custom styling
  • Content tabs, annotations, and diagrams (Mermaid integration)
  • Social cards (auto-generated Open Graph images)

MkDocs is ideal for projects that want a polished documentation site with minimal setup. The Material theme provides so many features out of the box that most projects never need to write custom CSS or templates.

Jekyll (Ruby, GitHub Pages native)

Jekyll is one of the oldest and most established static site generators. It is built in Ruby and has a special relationship with GitHub Pages — GitHub will build and host Jekyll sites automatically with no CI configuration required. You push Markdown files to a repository, and GitHub Pages builds and deploys the site.

Jekyll uses the Liquid templating language and has a vast ecosystem of themes and plugins. While it is a general-purpose static site generator rather than documentation-specific, many documentation themes are available, and its simplicity makes it easy to get started.

The CodeFrog help site uses Jekyll with GitHub Pages. This choice was made for its simplicity, zero-cost hosting, and the seamless deployment workflow — merging to main automatically publishes documentation updates.

Hugo (Go, fast builds)

Hugo is a static site generator written in Go, known for its extraordinary build speed. Hugo can build a site with thousands of pages in under a second, making it ideal for large documentation projects where build time matters. It ships as a single binary with no dependencies, making installation trivial.

Hugo supports multiple content formats, has a powerful templating system, and offers documentation-specific themes like Hugo Book and Docsy. It is a strong choice for projects that prioritize build performance or already have Go expertise on the team.

CI Checks for Documentation

Treating documentation as code means applying the same quality gates to docs that you apply to source code. Just as you would not merge code without tests passing, you should not merge documentation without quality checks passing.

Broken link detection

Broken links are one of the most common and frustrating documentation problems. A link that worked when the docs were written may break when the target page is renamed, moved, or deleted. CI tools like markdown-link-check, lychee, and htmlproofer (for built HTML) scan your documentation for broken internal and external links and fail the build if any are found.

Spell checking

Spelling errors in documentation undermine credibility. Tools like cspell and aspell can be integrated into CI to check spelling across all documentation files. Custom dictionaries allow you to add technical terms, product names, and acronyms that standard dictionaries do not include.

Prose linting with Vale

Vale is a prose linter — it checks your documentation for style, grammar, and consistency issues. Vale is configurable with style packages that enforce specific writing standards. You can use existing packages (Google Developer Documentation Style Guide, Microsoft Writing Style Guide, write-good) or create your own rules.

Vale catches issues like:

  • Passive voice ("The button was clicked" vs. "Click the button")
  • Weasel words ("very," "simply," "just," "basically")
  • Inconsistent terminology (using both "click" and "press" for the same action)
  • Complex sentences that exceed readability thresholds
  • Jargon and acronyms used without definition

Running Vale in CI ensures that all documentation meets your style standards before it is merged, regardless of who wrote it.

Versioned Documentation for Multiple Releases

When your project maintains multiple active versions, your documentation needs to match. A user on version 1.x needs documentation for version 1.x, not the bleeding-edge documentation for version 3.x. Versioned documentation ensures that every user sees the docs that match their installed version.

Most documentation static site generators support versioning natively or through plugins:

  • Docusaurus: Built-in versioning with docusaurus docs:version command. Creates a snapshot of your current docs and maintains it alongside the latest version.
  • MkDocs: The mike plugin provides multi-version documentation deployment to GitHub Pages.
  • Read the Docs: Automatically builds and hosts documentation for every branch and tag, with a version selector in the UI.

When implementing versioned docs, clearly indicate the current version in the UI and provide a way for users to switch versions. Mark older versions with a banner indicating that newer documentation is available.

Search Integration

As documentation grows, search becomes essential. Users should not have to browse through a sidebar or table of contents to find what they need — they should be able to type a query and get results instantly.

Algolia DocSearch

Algolia DocSearch is a free search service for open-source documentation sites. Algolia crawls your documentation, indexes it, and provides a search widget that delivers instant, typo-tolerant results. Many popular documentation sites use DocSearch, including React, Vue.js, Tailwind CSS, and Docusaurus itself.

Lunr.js

Lunr.js is a client-side search library that builds a search index at build time and runs searches entirely in the browser. It requires no external service, making it ideal for documentation sites that need to work offline or that prefer not to depend on third-party services. MkDocs Material uses a Lunr-based search by default.

Regardless of the search solution you choose, test your search regularly. Try searching for common terms that your users would use, and verify that the results are relevant and well-ranked.

Resources

  • Docusaurus — React-based documentation static site generator by Meta
  • MkDocs Material — The most popular MkDocs theme for technical documentation
  • Vale prose linter — A syntax-aware linter for prose, configurable with style packages