Migrating from blockdiag/seqdiag to Mermaid

This guide explains why the ONAP documentation project is replacing sphinxcontrib-blockdiag and sphinxcontrib-seqdiag with sphinxcontrib-mermaid, and provides instructions for migrating existing diagrams.

Background

The ONAP documentation toolchain has historically used two Sphinx extensions from the blockdiag family for embedding diagrams in reStructuredText:

  • sphinxcontrib-blockdiag — block (box-and-arrow) diagrams

  • sphinxcontrib-seqdiag — sequence diagrams

Both extensions are now effectively abandoned and cause cascading build failures across ONAP repositories. This document details the problems, evaluates alternatives, and provides a concrete migration path.

Problem statement

Both packages were last released on 2021-12-05 (version 3.0.0) and have received no maintenance since. Their classifiers list only Python 3.7–3.9 as supported. The underlying blockdiag rendering library on which they depend has the same maintenance status.

The lack of maintenance creates two critical incompatibilities that currently break ONAP documentation builds.

Python 3.12+ incompatibility

sphinxcontrib-blockdiag (and its dependency blockdiag) uses ast.NameConstant, which was deprecated in Python 3.8 and removed in Python 3.12. Any documentation build running on Python 3.12 or later will crash with an AttributeError.

Repositories that set basepython = python3 in tox.ini without pinning a version are particularly affected, because modern CI runners resolve this to Python 3.12 or newer.

Pillow 10+ incompatibility

blockdiag 3.0.0 calls ImageDraw.textsize(), a method that was deprecated in Pillow 9.2.0 and removed in Pillow 10.0. The ONAP upper-constraints file pins Pillow===10.4.0, so every repository that renders a .. blockdiag:: directive fails with:

AttributeError: 'ImageDraw' object has no attribute 'textsize'

The current workaround—forcing Pillow<10 via commands_pre in tox.ini—limits those repositories to Python 3.11 (Pillow 9.x does not ship wheels for Python 3.12+), prevents them from receiving Pillow security updates, and adds fragile per-repository configuration that is easy to forget.

Impact on ONAP repositories

The following table summarises how these incompatibilities have affected ONAP documentation builds:

Affected Repositories and Workarounds

Repository

Issue

Current Workaround

dmaap/buscontroller

Pillow/blockdiag crash

python3.11 + Pillow<10

dmaap/datarouter

Pillow/blockdiag crash

python3.11 + Pillow<10

sdc/sdc-docker-base

ast.NameConstant crash on Python 3.12+

None (build broken)

ccsdk/distribution

Extensions loaded but no directives in use

Pinned constraints

Evaluation of alternatives

Three actively maintained Sphinx extensions can produce the same types of diagrams that blockdiag and seqdiag provide.

sphinxcontrib-plantuml (already in use)

PyPI

sphinxcontrib-plantuml

Repository

https://github.com/sphinx-contrib/plantuml/

Latest release

0.31 (2025-09-03)

Python support

No explicit constraint (works with 3.8+)

Diagram types

Sequence, class, activity, component, state, object, deployment, timing, and many more

External tools

Requires Java and the PlantUML JAR file

ONAP already uses sphinxcontrib-plantuml in several repositories. PlantUML is a capable alternative but requires a Java runtime, which adds complexity to CI environments and local developer setups.

sphinx.ext.graphviz (built-in)

Documentation

sphinx.ext.graphviz

Maintenance

Maintained as part of Sphinx itself

Diagram types

Directed and undirected graphs

External tools

Requires the Graphviz dot binary

Graphviz is well suited for dependency graphs and network topologies. It is less natural for sequence diagrams and does not support the box-and-arrow style that blockdiag provides.

Comparison matrix

Extension Comparison

Criterion

blockdiag/seqdiag

Mermaid

PlantUML

Graphviz

Actively maintained

No (last release 2021)

Yes (2026-01)

Yes (2025-09)

Yes (part of Sphinx)

Python 3.12+ support

No

Yes (to 3.14)

Yes

Yes

Pillow dependency

Yes (broken >=10)

No

No

No

Block diagrams

Yes

Yes

Yes

Partial

Sequence diagrams

Yes

Yes

Yes

No

External runtime

None

None (HTML)

Java

Graphviz binary

GitHub rendering

No

Yes (native)

No

No

Single extension for both

No (two packages)

Yes

Yes

No

Recommendation

Replace both sphinxcontrib-blockdiag and sphinxcontrib-seqdiag with sphinxcontrib-mermaid.

Key reasons:

  1. One package replaces two — Mermaid handles both block and sequence diagrams (and many more types) with a single Sphinx extension.

  2. No Pillow dependency — eliminates the entire ImageDraw.textsize() / Pillow<10 compatibility problem.

  3. No Java dependency — unlike PlantUML, Mermaid renders via JavaScript for HTML output, with no external binary required for the most common build target.

  4. Python 3.10–3.14 support — future-proof, with no ast.NameConstant issues.

  5. Actively maintained — regular release cadence, latest release January 2026.

  6. Industry standard — Mermaid is natively rendered by GitHub, GitLab, Notion, Obsidian, and many other platforms, so contributors can preview diagrams without building the full documentation.

  7. ReadTheDocs compatible — works with the Sphinx HTML builder without any server-side tools.

Migration guide

This section provides step-by-step instructions for migrating a repository from blockdiag/seqdiag to Mermaid.

Step 1 — Update docs/conf.py

Remove the old extensions and add the Mermaid extension:

# Before
extensions = [
    'sphinx.ext.intersphinx',
    'sphinx.ext.graphviz',
    'sphinxcontrib.blockdiag',
    'sphinxcontrib.seqdiag',
    'sphinxcontrib.plantuml',
]

# After
extensions = [
    'sphinx.ext.intersphinx',
    'sphinx.ext.graphviz',
    'sphinxcontrib.mermaid',
    'sphinxcontrib.plantuml',
]

Step 2 — Update requirements-docs.txt

Replace the diagram extension entries:

# Before
sphinxcontrib-blockdiag>=3.0.0
sphinxcontrib-seqdiag>=3.0.0

# After
sphinxcontrib-mermaid>=1.0.0

If your repository also has an upper-constraints.onap.txt or similar constraints file, update it accordingly:

# Before
sphinxcontrib-blockdiag===3.0.0
sphinxcontrib-seqdiag===3.0.0

# After
sphinxcontrib-mermaid===2.0.0

Step 3 — Remove Pillow workarounds from tox.ini

If your tox.ini contains workarounds for the Pillow/blockdiag incompatibility, they can be removed:

# Remove this line if present:
commands_pre = pip install 'Pillow<10'

You can also upgrade basepython from python3.11 to python3.12 (or later) if it was held back specifically for blockdiag compatibility.

Step 4 — Convert blockdiag directives to Mermaid

Each .. blockdiag:: directive must be rewritten as a .. mermaid:: directive. The examples below cover the most common patterns.

Simple block diagram

.. blockdiag::

   blockdiag {
     A -> B -> C;
          B -> D;
   }

Becomes:

.. mermaid::

   graph LR
     A --> B --> C
     B --> D

Block diagram with labels and colours

.. blockdiag::

   blockdiag {
     A [label = "Client"];
     B [label = "Server", color = "#FF6600"];
     C [label = "Database"];
     A -> B -> C;
   }

Becomes:

.. mermaid::

   graph LR
     A["Client"] --> B["Server"] --> C["Database"]
     style B fill:#FF6600,color:#fff

Block diagram with groups

.. blockdiag::

   blockdiag {
     A -> B -> C;

     group {
       label = "Group 1";
       color = "#99CCFF";
       A; B;
     }
   }

Becomes:

.. mermaid::

   graph LR
     subgraph Group 1
       A --> B
     end
     B --> C

Vertical orientation

blockdiag renders left-to-right by default. If you need top-to-bottom flow (or if the original used orientation = portrait):

.. mermaid::

   graph TB
     A --> B --> C

The orientation keyword controls layout direction:

  • graph LR — left to right (default blockdiag style)

  • graph TB — top to bottom

  • graph RL — right to left

  • graph BT — bottom to top

Step 5 — Convert seqdiag directives to Mermaid

Each .. seqdiag:: directive must be rewritten as a .. mermaid:: directive using the sequenceDiagram type.

Simple sequence diagram

.. seqdiag::

   seqdiag {
     browser => webserver => database;
   }

Becomes:

.. mermaid::

   sequenceDiagram
     browser->>webserver: request
     webserver->>database: query
     database-->>webserver: result
     webserver-->>browser: response

Note

Mermaid sequence diagrams require explicit message labels on every arrow. The seqdiag shorthand A => B => C; (which implies unlabelled request-response pairs) must be expanded into individual messages with descriptive labels. This improves documentation clarity.

Sequence diagram with labels and notes

.. seqdiag::

   seqdiag {
     browser -> webserver [label = "GET /index.html"];
     browser <-- webserver [label = "200 OK"];

     browser -> webserver [label = "POST /api/data"];
     browser <-- webserver [label = "201 Created"];
   }

Becomes:

.. mermaid::

   sequenceDiagram
     browser->>webserver: GET /index.html
     webserver-->>browser: 200 OK
     browser->>webserver: POST /api/data
     webserver-->>browser: 201 Created

Sequence diagram with activation and notes

.. seqdiag::

   seqdiag {
     browser -> webserver [label = "request"];
     webserver -> database [label = "query"];
     webserver <-- database [label = "result"];
     webserver -> webserver [label = "process"];
     browser <-- webserver [label = "response"];
   }

Becomes:

.. mermaid::

   sequenceDiagram
     browser->>webserver: request
     activate webserver
     webserver->>database: query
     database-->>webserver: result
     webserver->>webserver: process
     webserver-->>browser: response
     deactivate webserver

Mermaid arrow syntax reference

Mermaid Sequence Diagram Arrow Types

Arrow

Meaning

seqdiag equivalent

->>

Solid line with arrowhead (synchronous)

-> or =>

-->>

Dashed line with arrowhead (response)

<-- or <==

-)

Solid line with open arrowhead (asynchronous)

-> (no direct equivalent)

--)

Dashed line with open arrowhead

(no direct equivalent)

-x

Solid line with cross (lost message)

(no direct equivalent)

Step 6 — Configure Mermaid options (optional)

You can add optional Mermaid configuration to conf.py:

# Use a specific Mermaid JS version (default: latest)
mermaid_version = "11.4.1"

# Generate raw Mermaid source alongside images for accessibility
mermaid_output_format = "raw"

# For PDF output, specify the mmdc CLI path (requires Node.js)
# mermaid_cmd = "/usr/local/bin/mmdc"

For HTML output (including ReadTheDocs), no additional configuration is needed. The extension embeds Mermaid.js from a CDN by default.

Step 7 — Verify the build

Run the documentation build locally and check that all diagrams render correctly:

cd <repository>
tox -edocs

Open the generated HTML in a browser and visually inspect each diagram.

Changes to the doc repository

The central doc repository files will be updated as part of this migration:

docs/conf.py

Remove sphinxcontrib.blockdiag and sphinxcontrib.seqdiag from the extensions list. Add sphinxcontrib.mermaid.

docs/requirements-docs.txt

Remove sphinxcontrib-blockdiag and sphinxcontrib-seqdiag. Add sphinxcontrib-mermaid>=1.0.0.

etc/upper-constraints.onap.txt

Remove sphinxcontrib-blockdiag===3.0.0 and sphinxcontrib-seqdiag===3.0.0. Add sphinxcontrib-mermaid===2.0.0. The Pillow pin can remain at 10.4.0 as Mermaid does not depend on it.

These changes will propagate to all downstream repositories that inherit the shared documentation configuration.

Downstream repository checklist

For each repository that currently uses blockdiag or seqdiag directives, the following changes are required:

Migration Checklist

#

Action

Files

1

Replace sphinxcontrib.blockdiag and sphinxcontrib.seqdiag with sphinxcontrib.mermaid in the extensions list

docs/conf.py

2

Replace sphinxcontrib-blockdiag and sphinxcontrib-seqdiag with sphinxcontrib-mermaid in documentation requirements

docs/requirements-docs.txt

3

Update pinned versions if a local constraints file exists

etc/upper-constraints.onap.txt

4

Convert all .. blockdiag:: directives to .. mermaid:: using the syntax examples in this guide

docs/**/*.rst

5

Convert all .. seqdiag:: directives to .. mermaid:: using the syntax examples in this guide

docs/**/*.rst

6

Remove any commands_pre = pip install 'Pillow<10' workarounds

tox.ini

7

Upgrade basepython to python3.12 if it was pinned to python3.11 solely for blockdiag compatibility

tox.ini

8

Build locally and verify all diagrams render correctly

(local test)

Further reading

See also

The sphinxcontrib-needs package has the same pkg_resources dependency issue. See Migrating from sphinxcontrib-needs to sphinx-needs for the migration guide to its maintained successor sphinx-needs.

Appendix — Gerrit repository audit

A recursive audit of all ONAP project repositories in Gerrit was performed to determine the blast radius of the blockdiag/seqdiag deprecation. The results below identify every repository that contains live .. blockdiag:: or .. seqdiag:: directives — i.e.actual diagrams rendered in documentation content. Repositories that merely list the packages in conf.py, requirements-docs.txt, tox.ini, or constraint files (without using any directives) are not included; those files need only a configuration cleanup, not a content migration.

Repositories with live blockdiag directives

#

Repository

File

Directives

Description

1

dmaap/buscontroller

docs/architecture.rst

1

Box-and-arrow diagram showing Bus Controller API connections to MR, DR and AAF

2

dmaap/datarouter

docs/delivery.rst

1

Container-connectivity diagram for DR-PROV, DR-NODE and MariaDB

3

sdc

docs/delivery.rst

2

Deployment dependency map (init jobs → apps → Cassandra) and docker-container connectivity diagram

4

sdnc/oam

docs/delivery.rst

1

Example block diagram with grouped layers

Repositories with live seqdiag directives

#

Repository

File

Directives

Description

1

vnfrqts/requirements

docs/Chapter8/ves7_1spec.rst

2

VES v7.1 call-flow diagrams for publishAnyEvent and publishEventBatch

2

vnfrqts/requirements

docs/Chapter8/ves_7_2/ves_event_listener_7_2.rst

2

VES v7.2 call-flow diagrams for publishAnyEvent and publishEventBatch

Audit summary

Metric

Count

Repositories with live .. blockdiag:: directives

4

Repositories with live .. seqdiag:: directives

1

Total .. blockdiag:: directives to rewrite

5

Total .. seqdiag:: directives to rewrite

4

Total diagrams requiring migration

9

Migration priority

All nine diagrams must be rewritten to .. mermaid:: directives before the affected repositories can build successfully on Python 3.12+. The recommended order is:

  1. ``sdc`` — two block diagrams, highest visibility project.

  2. ``dmaap/buscontroller`` and ``dmaap/datarouter`` — one block diagram each; both DMaaP repos can be migrated together.

  3. ``sdnc/oam`` — one example block diagram in the delivery page.

  4. ``vnfrqts/requirements`` — four sequence diagrams across two VES specification files (v7.1 and v7.2); the diagrams are structurally identical so a single pattern covers all four.

Note

In addition to the five repositories above, 32 further repositories load sphinxcontrib.blockdiag and sphinxcontrib.seqdiag in their docs/conf.py and declare them in docs/requirements-docs.txt without ever using a directive. Those repositories require only the configuration cleanup described in the downstream repository checklist (steps 1–3) and do not need any RST content changes.