Skip to main content

Docs as Code

· 6 min read
Max Kaido
Architect

Below are five approaches to embedding and managing documentation close to the code. We’ll incorporate the newly added Functional Design Document (FDD) approach into the comparison, combining it with the previously discussed four (Functional Flow Diagrams (FFD), ADRs, Docusaurus, and TypeDoc). After outlining all five and showing how to combine them, we’ll determine the best pair if you can only choose two.

The Five Approaches

  1. Functional Flow Diagrams (FFD) Concept: Visual diagrams (e.g., using Mermaid, PlantUML) stored in the repo to illustrate system workflows, user journeys, and data pipelines. Strengths:

    • Quickly communicate complex processes visually.
    • Easy to update as code changes, preventing outdated architecture diagrams. Limitations:
    • Purely visual; may lack detailed context or reasoning.
  2. Architecture Decision Records (ADRs) Concept: Markdown files documenting architecture decisions—context, decision, consequences—versioned with the code. Strengths:

    • Creates a historical rationale for architectural and technical choices.
    • Lightweight and easy to maintain. Limitations:
    • Doesn’t cover day-to-day workflows or detailed user guides.
  3. Docusaurus (Docs-as-Code Portal) Concept: A static site generator that turns Markdown docs in the repo into a searchable documentation website. Strengths:

    • Centralized documentation portal for guides, references, and tutorials.
    • Simple CI integration and versioning. Limitations:
    • Requires some effort to maintain structure and navigation.
    • Doesn’t automatically generate API docs from code comments (without additional tools).
  4. TypeDoc (Automated API Documentation) Concept: Generates API docs from TypeScript code comments (docstrings). Strengths:

    • Ensures API references are always up-to-date with code changes.
    • Lowers manual effort for maintaining API docs. Limitations:
    • Limited to technical/API-level documentation.
    • Requires consistent commenting habits from the dev team.
  5. Functional Design Document (FDD) Concept: A textual design document describing system behavior, feature specifications, and design constraints stored near the code. Strengths:

    • Provides detailed, narrative-style explanations of system functionality and design rationale.
    • Serves as a living specification that evolves with the code. Limitations:
    • Risk of becoming stale if not regularly updated.
    • Less automated than TypeDoc—requires manual effort to keep in sync.

Detailed Comparison of FDD (the Newly Added Approach)

FDD focuses on capturing the functional aspects of the system in a structured, descriptive manner. It might include:

  • Feature descriptions: outlining what each feature does, intended use cases, and requirements.
  • Interaction details: how components interact, potentially referenced from FFDs.
  • Constraints and assumptions that guide implementation.

Benefits of FDD:

  • Acts as a single source of truth for feature behavior and system design constraints.
  • Complements ADRs by providing more day-to-day implementation details, while ADRs cover high-level decision points.
  • Ensures developers and stakeholders can understand the system’s purpose and logic without diving directly into code.

Drawbacks of FDD:

  • Requires manual maintenance. If the code changes and no one updates the FDD, it can quickly become outdated.
  • Less automated than TypeDoc—FDD doesn't generate docs from code; it's a curated document.

Ideal Use Cases for FDD:

  • Complex features where a narrative explanation helps new developers or stakeholders understand the intended behavior.
  • Systems where business logic needs clear and persistent documentation, serving as a reference for QA, product managers, or new hires.

Combining All Five Approaches

Each approach complements the others:

  • FFD (Functional Flow Diagrams):

    • Use for visualizing complex flows and architecture. Integration:
    • Link diagrams from your Docusaurus docs pages.
    • Reference these diagrams in the FDD for visual support.
  • ADRs (Architecture Decision Records):

    • Keep a historical record of why certain architectural decisions were made. Integration:
    • Link ADRs from Docusaurus for easy navigation.
    • Mention relevant ADRs in FDD sections discussing related features or architectures.
  • Docusaurus:

    • Provide a central documentation portal. Integration:
    • Host FDDs, ADRs, and FFDs as Markdown pages within Docusaurus.
    • Include a dedicated section for TypeDoc-generated API docs.
    • Add links to diagrams and ADRs for cross-referencing.
  • TypeDoc:

    • Generate API-level docs directly from code comments. Integration:
    • Output TypeDoc-generated HTML or Markdown into a docs/api directory consumed by Docusaurus.
    • Reference TypeDoc sections in the FDD or ADRs for technical details on specific classes or functions.
  • FDD (Functional Design Document):

    • Detailed narrative explaining features and system design logic. Integration:
    • Store FDD files in docs/fdd within the repository.
    • Link from the FDD to relevant ADRs for architectural context, TypeDoc pages for low-level APIs, and FFDs for visual flows.
    • Reference FDD sections in commit messages when features evolve.

Example Workflow:

  1. New Feature Implementation:

    • Create or update an ADR if the feature involves a significant architectural choice.
    • Draft a Functional Design Document (FDD) section explaining the feature in detail—include functional requirements, expected behavior, constraints.
    • Produce or update Functional Flow Diagrams (FFD) to illustrate new workflows.
    • Add or update code comments so TypeDoc reflects any new classes or interfaces.
    • Update Docusaurus to link to the FDD, ADR, FFD diagrams, and TypeDoc API references.
  2. Maintenance and Updates:

    • When code changes, update the corresponding FDD sections and re-run TypeDoc to regenerate API docs.
    • Review ADRs to see if any decisions need revisiting.
    • Adjust diagrams (FFD) if workflows change.
    • CI updates the Docusaurus site so everyone has a central, updated doc portal.

Choosing Only Two Approaches for the Best Balance

If you must choose only two from FFD, ADR, Docusaurus, TypeDoc, and FDD:

  1. Docusaurus: Offers a broad framework for maintaining all kinds of documentation. You get a structured website, versioning, search, and easy linking between documents.

  2. FDD (Functional Design Document): Provides a narrative, human-readable, feature-focused explanation of how and why things work. It bridges the gap between code and high-level conceptual docs.

Why These Two?

  • Docusaurus gives you the organizational backbone—your entire documentation becomes a cohesive website.
  • FDD ensures you have detailed, feature-level documentation near the code, serving as a single source of truth for the functionality and logic.

This combination provides a strong balance of narrative depth (FDD) and a convenient, accessible docs platform (Docusaurus). While ADRs, TypeDoc, and FFDs are valuable, if limited to two:

  • Docusaurus ensures a well-structured doc portal.
  • FDD offers comprehensive, living documentation of feature logic and system behavior.

Conclusion: All five approaches—FFD, ADR, Docusaurus, TypeDoc, and FDD—together create a robust documentation ecosystem. If choosing just two, Docusaurus and FDD provide the best balance: a flexible docs platform (Docusaurus) and in-depth functional specifications (FDD) to keep your team aligned and informed.


If you can choose only three approaches, the best combination for maintaining a well-rounded, efficient, and scalable documentation system is:

Docusaurus + FDD (Functional Design Document) + TypeDoc


Why These Three?

  1. Docusaurus (Centralized Documentation Portal):

    • Acts as the organizational backbone for your documentation.
    • Combines flexibility (Markdown, navigation, search) with scalability (CI integration, versioning).
    • Provides a unified place for hosting FDDs, TypeDoc outputs, and any other supplementary documentation (like ADRs or FFDs, if included later).
  2. FDD (Functional Design Document):

    • Covers the narrative and functional aspects of the project, detailing features, expected behavior, and design constraints.
    • Ensures a human-readable, contextual understanding of system functionality and design.
    • FDDs work as the "why and how" complement to Docusaurus and TypeDoc.
  3. TypeDoc (Automated API Documentation):

    • Automates API-level documentation directly from your codebase.
    • Provides consistent and always-updated documentation for developers working with your APIs.
    • Reduces manual effort by generating documentation for classes, interfaces, and functions.

Use Cases and Workflow for the Combination

Scenario: Adding a New Feature

  1. Document the Design and Functionality:

    • Create or update an FDD in docs/fdd, explaining:
      • The feature’s purpose, expected functionality, and constraints.
      • How it interacts with existing components or modules.
    • Include relevant diagrams (optional, manually created or linked).
  2. Generate API Documentation:

    • Write clear, structured comments in your TypeScript codebase.
    • Use TypeDoc to regenerate the API documentation as part of your CI/CD pipeline.
    • Place the generated docs in a docs/api folder consumed by Docusaurus.
  3. Publish Documentation via Docusaurus:

    • Add FDD, TypeDoc outputs, and related Markdown files to Docusaurus.
    • Structure the sidebar to link FDDs, API docs, and any supplementary content (e.g., deployment guides).
    • Use Docusaurus’s search and navigation features to make the content easy to access for your team or stakeholders.

Benefits of Choosing These Three

  1. Comprehensive Coverage:

    • Docusaurus provides a centralized, searchable structure for all types of documentation.
    • FDD adds depth by documenting functionality and purpose in detail.
    • TypeDoc ensures technical and API-level documentation is always in sync with the code.
  2. Balance of Automation and Manual Effort:

    • TypeDoc automates API documentation, reducing manual work.
    • FDDs require manual updates but provide crucial context and narrative, filling gaps TypeDoc can’t address.
    • Docusaurus ties everything together, ensuring easy access and maintenance.
  3. Scalability:

    • This trio can scale across teams and project sizes.
    • Additional approaches like ADRs or FFDs can be layered in later without disrupting the structure.

When to Use Each Approach

  • Docusaurus:

    • Use as the central hub for all documentation types.
    • Perfect for hosting high-level guides, tutorials, and navigation to FDDs and TypeDoc.
  • FDD:

    • Write FDDs for major features or complex functionalities that require detailed explanations.
    • Include feature specs, use cases, and constraints here.
  • TypeDoc:

    • Use for API documentation, particularly for developers who need to understand the technical details of your codebase.
    • Generate automatically to minimize the risk of outdated documentation.

If Expanding Later

If you decide to expand beyond these three, ADRs (for architectural decisions) and FFDs (for workflows) can be layered on top. This three-approach setup ensures a strong foundation while remaining extensible.


Final Recommendation

For the best balance with three approaches:

  1. Docusaurus for centralized access.
  2. FDD for detailed functional explanations.
  3. TypeDoc for automated technical documentation.

This combination provides structured, accessible, and consistently updated documentation with a manageable level of effort.