How to Add Custom Icons to Architecture Diagrams in Diagram Design

To add custom icons to architecture diagrams, create a 24×24 px monochrome SVG using currentColor, register it in the primitive-icons.md catalog, and reference the icon name in your component definitions.

The Diagram Design framework (cathrynlavery/diagram-design) ships with a curated set of 24×24 px monochrome icons stored in a centralized catalog. By extending this catalog with your own SVG definitions, you can render custom graphics that automatically inherit the diagram’s color theme and align perfectly with text baselines.

SVG Requirements for Custom Icons

All custom icons must conform to the engine’s strict specifications to ensure consistent rendering.

  • Canvas size: Exactly 24 × 24 pixels with a viewBox="0 0 24 24"
  • Color inheritance: Use stroke="currentColor" for line icons or fill="currentColor" for solid silhouettes to enable automatic theme switching
  • Stroke weight: 1.5 px hair-line strokes (stroke-width="1.5")
  • Style constraints: No gradients or complex filters—the engine expects simple paths that render crisply at small sizes

Step-by-Step: Adding a Custom Icon

Create the SVG File

Design your icon in a vector editor, ensuring it fits within the 24×24 pixel grid. The SVG must use currentColor to inherit the surrounding text color.

<svg aria-hidden="true" width="24" height="24"
     viewBox="0 0 24 24" fill="none"
     stroke="currentColor" stroke-width="1.5"
     stroke-linecap="round" stroke-linejoin="round">
  <path d="M4 4h16v16H4z"/>
  <path d="M8 8h8v8H8z"/>
</svg>

Register in the Icon Catalog

Open skills/diagram-design/references/primitive-icons.md and add a new ATX heading (###) followed by your fenced SVG block. The heading text becomes the icon’s reference name.


### my-custom-icon

```svg
<svg aria-hidden="true" width="24" height="24"
     viewBox="0 0 24 24" fill="none"
     stroke="currentColor" stroke-width="1.5"
     stroke-linecap="round" stroke-linejoin="round">
  <path d="M4 4h16v16H4z"/>
  <path d="M8 8h8v8H8z"/>
</svg>

### Reference in Diagram Definitions

In your diagram YAML files, set the `icon` field to the name you defined in the catalog (e.g., `my-custom-icon`). As shown in [`skills/diagram-design/references/type-it-state.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/type-it-state.md), the engine reads this field and positions the icon 24 px to the left of the component name.

```yaml
components:
  - id: my-service
    name: My Service
    sub: "demo component"
    icon: my-custom-icon   # ← references the catalog entry

    kind: focal

How the Rendering Engine Processes Icons

When the diagram generator encounters an icon field, it performs a lookup in primitive-icons.md for a matching ### heading. Upon finding the entry, the engine injects a <use> element into the generated SVG that references the icon definition via a hashed identifier.

According to the rendering implementation in type-it-state.md, the output resembles:

<g transform="translate(x,y)">
  <use href="#icon-my-custom-icon"/>
  <text x="30" y="12">My Service</text>
</g>

This approach ensures that icons remain symbolic references rather than embedded duplicates, keeping file sizes small and allowing global style updates to propagate instantly.

Best Practices for Icon Design

Maintain monochrome simplicity. The engine expects single-color assets that adapt to light and dark themes automatically. Using currentColor binds the icon stroke to the CSS color of its parent element.

Align to the pixel grid. Because the icons render at exactly 24 × 24 px, ensure your paths sit on whole pixels to prevent anti-aliasing blur at the 1.5 px stroke weight.

Test bulk additions. When adding multiple custom icons, use the scripts/test-build-icons-devicon.py script to validate that your SVGs compile correctly into the symbol library before committing changes.

Summary

  • Add custom icons by editing skills/diagram-design/references/primitive-icons.md in the cathrynlavery/diagram-design repository
  • Strictly adhere to 24×24 px dimensions and currentColor for theme compatibility
  • Reference icons in YAML via the icon: field; the engine injects <use href="#icon-{name}"/> during rendering
  • Keep strokes at 1.5 px and avoid gradients for consistent hair-line rendering
  • Changes to the catalog propagate immediately to all diagrams referencing those icons

Frequently Asked Questions

What file format does Diagram Design require for custom icons?

Diagram Design requires SVG format only. The icons must be embedded as fenced code blocks within the primitive-icons.md markdown file, not stored as separate .svg files. The engine parses these blocks and extracts the <svg> elements to build an internal symbol library.

Can I use colored icons or gradients in my architecture diagrams?

No. The rendering engine strictly expects monochrome icons using stroke="currentColor" or fill="currentColor". Gradients, multiple colors, or fixed hex values break the automatic theme switching and may cause rendering errors when the diagram switches between light and dark modes.

How do I know if my icon is properly registered in the catalog?

After adding your icon to primitive-icons.md under a heading like ### my-icon, you can verify registration by referencing icon: my-icon in any component definition. If the heading name matches exactly (case-sensitive), the generated diagram will display your icon 24 pixels to the left of the component text. The scripts/test-build-icons-devicon.py script can also validate SVG syntax before you commit.

Will custom icons work when importing Draw.io files into Diagram Design?

When importing Draw.io files via commands/import-drawio.md, the importer attempts to match embedded icons to the nearest entry in the primitive icon catalog. If an exact match exists for your custom icon, it will render correctly; otherwise, the engine falls back to the closest available catalog icon. To ensure custom icons persist through imports, standardize on the 24×24 px catalog format described above.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →