# How Diagram Types Are Loaded On-Demand in the Diagram‑Design Skill

> Learn how the diagram-design skill uses lazy loading to fetch diagram types on-demand, reducing I/O and parsing overhead for a faster user experience.

- Repository: [Cathryn Lavery/diagram-design](https://github.com/cathrynlavery/diagram-design)
- Tags: internals
- Published: 2026-09-06

---

**The diagram-design skill uses lazy loading to fetch type reference files from the `references/` directory only after a specific diagram kind has been selected, cutting unnecessary I/O and parsing overhead.**

The diagram-design skill in `cathrynlavery/diagram-design` implements a **just‑in‑time discovery pattern** that defers loading diagram type specifications until the exact moment they are needed. This article walks through the mechanics of on‑demand diagram type loading, from block detection to reference file parsing.

## Diagram Kind Detection and Selection

Every diagram type journey begins with identification. When the skill processes a source file—whether Mermaid, draw.io, or Markdown—it first surfaces what kinds of diagrams live inside.

### Automatic Kind Extraction

In [`skills/diagram-design/scripts/mermaid_extract.py`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/scripts/mermaid_extract.py), the extractor scans each block and assigns a **kind** via the `Diagram.kind` property:

```python

# mermaid_extract.py:L321-L326 – kind detection logic

# The line prefix determines the diagram type:

#   sequenceDiagram  →  kind = "sequence"

#   stateDiagram-v2  →  kind = "state"

#   erDiagram        →  kind = "er"

#   flowchart TD     →  kind = "flow"

```

This detection runs **before** any reference files touch disk. The skill knows what it might need, but does not yet fetch it.

### CLI-Driven Type Filtering

Users can narrow scope with the `--type` (or `--diagram`) flag. The helper `select_diagrams` enforces this filter:

```python

# mermaid_extract.py:L1299-L1306

def select_diagrams(diagrams, selector=None):
    if selector is None:
        return diagrams
    return [d for d in diagrams if d.kind == selector]

```

**Key point:** The selector reduces the working set to only the diagram kinds actually requested. Unselected kinds never trigger reference loading.

## Lazy Reference Loading

Once the target set is locked, the skill performs **on‑demand reference resolution**. This is the core optimization that keeps startup fast.

### The SKILL.md Contract

The [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) file explicitly documents this behavior:

> "Details load from `references/` **only when selected**."

This statement at `skills/diagram-design/SKILL.md:L13` governs the entire loading strategy. The table inside [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) maps each supported kind to its corresponding reference file:

| Diagram Kind | Reference File |
|--------------|----------------|
| `sequence` | `type‑sequence.md` |
| `state` | `type‑state.md` |
| `er` | `type‑er.md` |
| `flow` | `type‑flow.md` |

### Late Binding in the Render Path

The actual file open happens inside `to_json` (or the draw.io equivalent), immediately preceding HTML/SVG emission:

```python
def render(diagram):
    # Determine the reference file from the diagram kind

    ref_path = REFERENCE_ROOT / f"type-{diagram.kind}.md"
    # Load the markdown only when needed

    reference = markdown.parse(ref_path.read_text())
    # Use the reference to drive layout calculations

    layout = build_layout(diagram, reference)
    return layout.to_svg()

```

Because reference files are plain Markdown, the skill parses them fresh for each run. **No persistent cache** is maintained beyond the current execution context.

## Practical Usage Examples

### Command-Line Type Selection

Force the importer to handle only sequence diagrams:

```bash

# Import a Mermaid file, but only render “sequenceDiagram” blocks

diagram-design import-mermaid my-flow.mmd --type sequenceDiagram

```

The extractor keeps `sequenceDiagram` blocks; `select_diagrams` drops the rest. The lazy loader then reads `references/type‑sequence.md` exclusively.

### Programmatic Filtering

```python
from skills.diagram_design.scripts.mermaid_extract import parse_block, select_diagrams

# `diagrams` contains all blocks parsed from a file

selected = select_diagrams(diagrams, selector="stateDiagram-v2")

# Only state diagrams remain

# When to_json executes, only type-state.md is opened

json_output = to_json(Path("out.json"), diagrams, selected)

```

Unselected reference files—`type‑sequence.md`, `type‑er.md`, etc.—are never accessed.

## Why On-Demand Loading Matters

- **Performance:** With 39+ possible diagram types, eager loading would waste significant I/O and parsing time. The skill pays only for what it uses.
- **Extensibility:** Adding support for a new diagram type requires only a new `type‑<name>.md` file. The lazy loader discovers it automatically—no code changes needed.
- **Correctness:** The [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) mapping guarantees that each diagram kind receives exactly its designated reference, eliminating version mismatches.

## Key Source Files

| Role | Path | Responsibility |
|------|------|----------------|
| **Extractor & Selector** | [`skills/diagram-design/scripts/mermaid_extract.py`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/scripts/mermaid_extract.py) | `Diagram.kind` detection, `select_diagrams` filtering, lazy loader trigger |
| **Reference Table** | [`skills/diagram-design/SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/SKILL.md) | Type-to-file mapping; lazy‑load policy statement |
| **Type References** | `skills/diagram-design/references/type‑*.md` | Grammar and layout rules; opened per‑kind on demand |
| **CLI Interface** | `commands/import‑mermaid.md` | `--type` flag specification |

## Summary

- **Diagram kind detection** runs early in [`mermaid_extract.py`](https://github.com/cathrynlavery/diagram-design/blob/main/mermaid_extract.py) to catalog available types without loading reference data.
- **User selection** via `--type` or programmatic filter reduces the candidate set before any file I/O occurs.
- **Lazy reference loading** pulls `type‑*.md` files only for kinds present in the final selection, as mandated by `SKILL.md:L13`.
- **No caching** persists between runs; references are parsed fresh each execution.
- **Extensibility is declarative:** new types need only a new markdown file in `references/`.

## Frequently Asked Questions

### What triggers diagram type loading in diagram-design?

Diagram type loading triggers only after `select_diagrams` has finalized the set of diagrams to render. At that point, `to_json` or the draw.io renderer looks up each diagram's kind in the [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) table and opens the matching `type‑*.md` reference file.

### Can I force the skill to load all diagram types at once?

No—and this is by design. The lazy loading mechanism has no eager-load switch. If you need guarantees about all types, you would need to supply input files containing at least one block of each desired kind.

### How do I add support for a new diagram type?

Create a new `type‑<yourname>.md` file in `skills/diagram-design/references/` and register the kind-to-file mapping in [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md). The extractor will detect blocks of that kind automatically, and the lazy loader will pick up your reference file the first time such a block is selected.

### Does diagram-design cache parsed reference files between runs?

No. Reference files are parsed on every run, with no persistent cache. This keeps the implementation stateless and ensures that edits to `type‑*.md` files take effect immediately without restart or invalidation logic.