# How to Add Custom Icons to Architecture Diagrams in Diagram Design

> Easily add custom icons to architecture diagrams. Create monochrome SVGs, register them in the primitive icons catalog, and reference them in your components.

- Repository: [Cathryn Lavery/diagram-design](https://github.com/cathrynlavery/diagram-design)
- Tags: how-to-guide
- Published: 2026-09-12

---

**To add custom icons to architecture diagrams, create a 24×24 px monochrome SVG using `currentColor`, register it in the [`primitive-icons.md`](https://github.com/cathrynlavery/diagram-design/blob/main/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
<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`](https://github.com/cathrynlavery/diagram-design/blob/main/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.

```markdown

### 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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/type-it-state.md), the output resembles:

```svg
<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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/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.