# How to Add Custom or Branded Icons to Diagram‑Design: A Complete Guide

> Learn to add custom or branded icons to diagram design. Register SVG symbols or embed PNGs directly to enhance your diagrams with this complete guide.

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

---

**You can add custom or branded icons to diagram‑design by either registering an SVG symbol in the icon library (referenced as `icon:name`) or embedding a custom PNG/image directly as a node in your source diagram.**

As of the latest release, diagram‑design supports two distinct pathways for incorporating non‑standard graphics: the **icon reference system** for scalable, theme‑aware symbols, and the **image embed system** for raster logos and photographs. This guide explains both approaches using actual source code locations from the `cathrynlavery/diagram-design` repository.

---

## Understanding the Two Icon Systems

Before adding icons, choose the approach that matches your asset type:

| Approach | Best For | Output Element | Source File |
|----------|----------|----------------|-------------|
| **Icon reference** (`icon:name`) | Brand logos, UI symbols, scalable graphics | `<use href="#icon‑{name}" />` | [`icons.html`](https://github.com/cathrynlavery/diagram-design/blob/main/icons.html) symbol definitions |
| **Custom image** | Photographs, complex raster logos, legacy assets | `<image href="..." />` | Draw.io `image` style nodes |

Both systems are handled by [`scripts/drawio_extract.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/drawio_extract.py), which processes source diagrams and emits the appropriate SVG elements.

---

## Method 1: Adding Custom Icons to the Icon Library

The **icon library** stores reusable SVG symbols that automatically inherit the diagram’s color scheme. This is the preferred method for branded icons you’ll use repeatedly.

### Step 1: Define the SVG Symbol

Open [`skills/diagram-design/assets/icons.html`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/assets/icons.html) and add a new `<symbol>` block:

```html
<symbol id="icon‑mybrand" viewBox="0 0 24 24">
  <path d="M12 2L2 22h20L12 2z" fill="currentColor"/>
</symbol>

```

Follow these conventions from the primitive icon system:

- Use `viewBox="0 0 24 24"` for consistency with built‑in icons.
- Apply `fill="currentColor"` or `stroke="currentColor"` so the icon adapts to theme colors.
- Keep paths optimized; the built‑in AWS icon uses this same pattern.

### Step 2: Reference in Your Diagram

In Mermaid YAML or Draw.io metadata, use the `icon` field:

```yaml
- { id: api-gateway, name: "API Gateway", icon: mybrand }

```

The renderer, per `type‑it‑state.md`, generates:

```svg
<use href="#icon‑mybrand" transform="translate(64 124)" style="color:#6366f1"/>

```

### Step 3: Verify in drawio_extract.py

The parser at lines 268‑279 of [`scripts/drawio_extract.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/drawio_extract.py) detects `shape.startswith("icon:")` and routes to the symbol reference path:

```python
if shape.startswith("icon:"):
    icon_name = shape[5:]  # strip 'icon:' prefix

    svg_element = f'<use href="#icon-{icon_name}" ... />'

```

---

## Method 2: Embedding Custom PNGs and Raster Images

For logos or graphics that cannot be converted to SVG paths, embed them as **image nodes**.

### In Draw.io Source Files

Set any shape’s style to `image` and provide a URL or data‑URI:

```xml
<mxCell style="shape=image;image=https://cdn.example.com/logo.png;..." ... />

```

Or use a base64‑encoded data‑URI for self‑contained diagrams:

```xml
shape=image;image=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34...

```

### How the Importer Handles Images

Per [`import-drawio.md`](https://github.com/cathrynlavery/diagram-design/blob/main/import-drawio.md), the importer creates an `image` node type:

| Property | Value |
|----------|-------|
| `type` | `image` |
| `src` | Original image URL or data‑URI |
| `preserveAspect` | `true` (default) |

The export stage renders this as a standard SVG `<image>` element:

```svg
<image href="https://cdn.example.com/logo.png" x="120" y="80" width="48" height="48"/>

```

### Important Limitations

- **Embedded images are not recolored** — they render exactly as provided, ignoring the diagram’s theme.
- **Missing images fallback** to a labeled rectangle; the tool never retains broken references.

---

## Registering Icons in the Primitive Catalog

To make custom icons discoverable, document them in [`skills/diagram-design/references/primitive-icons.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/primitive-icons.md). The built‑in catalog follows this format:

```markdown
| Icon | ID | Source |
|------|----|--------|
| AWS | `aws` | Official brand kit |
| Azure | `azure` | Microsoft design resources |
| MyBrand | `mybrand` | Custom addition |

```

This reference file is not enforced at runtime but aids maintainability and collaboration.

---

## Complete Workflow Example

Here’s an end‑to‑end example combining both methods:

**1. Register a custom SVG icon:**

```html
<!-- skills/diagram-design/assets/icons.html -->
<symbol id="icon‑acmecorp" viewBox="0 0 24 24">
  <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"/>
  <path d="M8 12l3 3 5-6" stroke="currentColor" stroke-width="2" fill="none"/>
</symbol>

```

**2. Create a diagram YAML file:**

```yaml
diagram:
  title: "Acme Corp Infrastructure"
  nodes:
    - { id: frontend, name: "Web App", icon: acmecorp }
    - { id: legacy, name: "Legacy DB", icon: image, src: "assets/legacy-db.png" }
  edges:
    - { from: frontend, to: legacy }

```

**3. Run the generator:**

```bash
python -m diagram_design generate infrastructure.yaml --output out.svg

```

The resulting `out.svg` contains both the themed `<use>` reference and the embedded `<image>` tag.

---

## Summary

- **Add SVG symbols to [`assets/icons.html`](https://github.com/cathrynlavery/diagram-design/blob/main/assets/icons.html)** for scalable, theme‑aware branded icons referenced as `icon:name`.
- **Use Draw.io `image` styles** for PNGs and raster assets that must preserve original appearance.
- **[`drawio_extract.py`](https://github.com/cathrynlavery/diagram-design/blob/main/drawio_extract.py) (lines 268‑279)** routes `icon:` prefixes to `<use>` elements; `image` types pass through as `<image>` tags.
- **[`import-drawio.md`](https://github.com/cathrynlavery/diagram-design/blob/main/import-drawio.md)** documents the `image` node type and its rendering behavior.
- Prefer the icon library for consistency; reserve image embeds for unavoidable raster content.

---

## Frequently Asked Questions

### How do I ensure my custom icon matches the diagram color theme?

Define your SVG symbol with `fill="currentColor"` or `stroke="currentColor"` in [`assets/icons.html`](https://github.com/cathrynlavery/diagram-design/blob/main/assets/icons.html). The renderer applies the node’s assigned color via inline `style="color: #hex"` on the `<use>` element.

### Can I use an external CDN URL for a custom icon?

Not directly through the `icon:` prefix — that requires a local symbol definition. For external images, use the **image embed method** with a full URL in the Draw.io `image` style property.

### What happens if I reference an icon that doesn’t exist?

The generator logs a warning and renders a fallback shape — typically a rectangle with the node label. The [`drawio_extract.py`](https://github.com/cathrynlavery/diagram-design/blob/main/drawio_extract.py) parser does not halt on missing icon definitions.

### Is there a size limit for embedded PNG images?

No hard limit is enforced in the source code, but large base64 data‑URIs increase file size and slow rendering. The [`primitive-icons.md`](https://github.com/cathrynlavery/diagram-design/blob/main/primitive-icons.md) documentation recommends optimizing raster assets to 48×48 or 96×96 display pixels.