- One catalog (1,555 Lucide 0.475.0 icons plus drop-in custom icons), the same names on every target
- Native rendering per target: inline
<svg>in Blazor, nativePathshapes in MAUI, direct drawing in Avalonia, all converted at build time - Typed components per icon that trim, plus a dispatcher when the icon is a value
- Zero JS and zero required CSS in Blazor
- Docs for AI agents:
/llms.txt, every page as Markdown, andAGENTS.md/CLAUDE.md/ Copilot / Cursor rule files (AI Agents)
| Package | Status | Readme |
|---|---|---|
ShellIcons.Blazor |
src/ShellIcons.Blazor | |
ShellIcons.Maui |
src/ShellIcons.Maui | |
ShellIcons.Avalonia |
src/ShellIcons.Avalonia |
Blazor:
dotnet add package ShellIcons.Blazor@using ShellIcons
<ChevronRightIcon />
<ZapIcon Size="16" StrokeWidth="1.5" />
<ShellIcon Name="@page.IconName" />.NET MAUI:
dotnet add package ShellIcons.Maui --prerelease<ContentPage xmlns:icons="https://shellicons.dev/maui">
<icons:ChevronRight Size="16" />
<icons:Icon Name="{Binding StatusIcon}" Color="{DynamicResource Primary}" />
</ContentPage>Avalonia:
dotnet add package ShellIcons.Avalonia --prerelease<Window xmlns:icons="https://shellicons.dev/avalonia">
<icons:ChevronRight Size="16" />
<icons:Icon Kind="{Binding StatusIcon}" Foreground="{DynamicResource AccentBrush}" />
</Window>Avalonia's dispatcher uses Kind because every Avalonia control already has Name. The full guides are in each package's readme and on the docs site.
shell-icons/
├── CHANGELOG.md release notes
├── RELEASING.md how to cut a release
├── LUCIDE_VERSION.txt pinned upstream tag
├── NOTICE.md Lucide ISC attribution
├── ShellIcons.slnx Blazor, Avalonia, generators, tests, docs — no MAUI workload needed
├── ShellIcons.Maui.slnx MAUI projects — needs `dotnet workload install maui`
├── Directory.Build.props
├── catalog/
│ ├── lucide/icons/ vendored Lucide SVGs (populated by sync-lucide.ps1)
│ └── custom/ repo-owned SVGs, drop-in
│ ├── README.md drop-in contract
│ └── icons/
├── scripts/
│ └── sync-lucide.ps1 refresh vendored Lucide catalog
├── src/
│ ├── ShellIcons.Blazor/ Razor Class Library (net8.0;net9.0)
│ ├── ShellIcons.Generator/ Blazor source generator (netstandard2.0)
│ ├── ShellIcons.Maui/ MAUI library (preview)
│ ├── ShellIcons.Avalonia/ Avalonia library (preview, net8.0)
│ └── ShellIcons.Generator.Xaml/ MAUI + Avalonia source generator, SVG → path conversion
├── tests/
│ ├── ShellIcons.Generator.Tests/ xUnit: SvgParser, Naming, path conversion
│ ├── ShellIcons.Blazor.Tests/ xUnit + bUnit: components, factory, dispatcher, collisions
│ ├── ShellIcons.Maui.Tests/ headless MAUI: controls, XAML, whole-catalog geometry
│ └── ShellIcons.Avalonia.Tests/ headless Avalonia with Skia: controls, XAML, renders of every icon
├── docs/
│ └── ShellIcons.Docs/ ShellDocs site — dev at http://localhost:5145
└── .github/workflows/
├── ci.yml ubuntu: ShellIcons.slnx · windows: ShellIcons.Maui.slnx
├── release.yml tag → all three packages on NuGet (Trusted Publishing) + GitHub Release
└── docs.yml static build → GitHub Pages
Run the docs locally:
cd docs/ShellIcons.Docs
dotnet runServes at http://localhost:5145. Pages live in docs/ShellIcons.Docs/content/docs/*.md. Live component previews via razor:preview code fences work out of the box.
/docs/icons is a searchable browser of the entire catalog with click-to-copy component names.
Build the static site the way the deploy workflow does (needs dotnet tool install -g ShellDocs.CLI --version 0.1.19-alpha):
cd docs/ShellIcons.Docs
shelldocs build --output ../../publish --spa-fallback --site-url https://shellicons.shellui.devEvery page under content/ is prerendered to plain HTML, so any static host can serve publish/. Pages added as Razor @page routes outside content/ are not prerendered — put new pages in content/ (a component can be used from markdown, as content/docs/icons.md does).
./scripts/sync-lucide.ps1 # pinned version
./scripts/sync-lucide.ps1 -Version 0.480.0 # bump + repinDrop an SVG into catalog/custom/icons/ and rebuild — the source generators pick it up and emit it into every package. Same 24×24 stroke contract as Lucide. See catalog/custom/README.md for the drop-in contract.
Custom icons live alongside Lucide-derived icons in the same namespace; consumers can't tell them apart. Use them for:
- Fill variants of Lucide icons (active-state UI, e.g.
HouseFillednext toHouse) - Brand marks and product-specific glyphs
- Full overrides of a Lucide icon — custom wins on name collision