# Custom icons > Drop your own SVGs alongside Lucide's — they compile in as first-class typed components. Source: https://shellicons.shellui.dev/docs/guides/custom-icons **Drop an SVG into `catalog/custom/icons/`. Rebuild. That's it.** The Roslyn source generator scans both `catalog/lucide/icons/` (vendored) and `catalog/custom/icons/` (repo-owned) and emits typed components from both packs into the same `ShellIcons.Icons` namespace. Consumers can't tell them apart. ## The SVG contract Match Lucide's format so custom icons feel visually cohesive: ```xml ``` - **viewBox** must be `0 0 24 24` - **stroke** must be `currentColor` — literal colors break theming - **stroke-width** is `2` - **stroke-linecap** and **stroke-linejoin** are `round` - **Inner elements** — any of ``, ``, ``, ``, ``, `` ## File naming `kebab-case.svg`. The file name becomes the component name: | File | Component | Dispatcher `Name` | |----------------------------|----------------------|------------------------| | `house-filled.svg` | `` | `"house-filled"` | | `my-brand-logo.svg` | `` | `"my-brand-logo"` | ## Fill variants — the classic use case Lucide is stroke-only. When you want a filled icon for active-state UI, draw it as a custom icon: ``` catalog/custom/icons/house-filled.svg ``` ```razor @if (activePage == "home") { } else { } ``` The filled variant should use `fill="currentColor"` on the shape elements that need to be solid. ## Optional metadata Drop `.json` next to the SVG: ```json { "tags": ["home", "filled", "active-state"], "aliases": ["home-solid"], "categories": ["navigation"], "deprecated": false } ``` Format mirrors Lucide's. Extra keys are ignored. ## Collision with Lucide If your file name matches a Lucide icon (e.g. `catalog/custom/icons/zap.svg` while Lucide also has `zap.svg`), **custom wins**. The generator treats it as a deliberate override and emits a `SHELLICONS001` build-log message so the swap is visible. Use this to swap out any Lucide icon you don't like without forking the whole catalog: ``` catalog/custom/icons/zap.svg ``` `` now renders your version everywhere. ## On MAUI Custom icons are converted for [MAUI](https://shellicons.shellui.dev/docs/maui/rendering.md) too. Keep them flat — no ``, no `transform`, every shape inside the 24×24 grid — and they render the same on every target. The build warns (`SHELLICONS002`) when something won't convert. ## Licensing Custom-pack icons are your own work under whatever license your project uses. They are **not** attributed in `NOTICE.md` — that file covers only the Lucide pack. If you fork this repo and add a lot of custom icons, treat them as first-class source code, not vendored content.