@canonical/svelte-icons
Canonical's design system icons packaged as Svelte 5 components. This library provides all icons from Canonical's Pragma design system as easy-to-use Svelte components.
[!WARNING] This package is it's experimental stage. It may undergo significant changes before reaching a stable release. It is not recommended for production use at this time.
Installation
bun add @canonical/svelte-icons
Usage
Basic Usage
Import icons individually and use them as components:
<script>
import { HomeIcon, SettingsIcon, UserIcon } from "@canonical/svelte-icons";
</script>
<HomeIcon />
<SettingsIcon class="custom-class" />
<UserIcon />
Styling Icons
Icons by default inherit the current text color and size.
<script>
import { SearchIcon } from "@canonical/svelte-icons";
</script>
<SearchIcon style="color: red; width: 2em; height: 2em;" />
Performance Optimization
When using the same icon multiple times, you may use IconsOptimizationProvider to deduplicate SVG definitions in the generated markup:
<script>
import { IconsOptimizationProvider, HomeIcon } from "@canonical/svelte-icons";
</script>
<IconsOptimizationProvider>
<nav>
<HomeIcon />
<!-- All instances share the same SVG definition -->
<HomeIcon />
<HomeIcon />
</nav>
</IconsOptimizationProvider>
This is especially useful when rendering the same icon many times.
Check out the Node tree size comparison story to see the DOM size difference between optimized and non-optimized rendering.
Custom Icons
You can also create custom icon components using the IconBase component:
<script>
import { IconBase } from "@canonical/svelte-icons";
</script>
<IconBase iconName="my-custom-icon">
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<circle cx="8" cy="8" r="6" stroke="black" stroke-width="1" fill="red" />
</svg>
</IconBase>
[!IMPORTANT] When using custom icons with
IconsOptimizationProvider:
- ensure that the
iconNameprop is unique for each custom icon to avoid collisions,- modifying the SVG content inside
IconBaseduring runtime may lead to unexpected behaviors.Check out the Reactivity playground story to learn more.
Icon Source
All SVG icons are sourced from the @canonical/ds-assets package, which is part of Canonical's Pragma design system.
Development
# Install dependencies
bun install
# Build icon components from source
bun run build
# Run Storybook for development
bun run storybook
# Lint, type check and verify metadata.json is up to date
bun run check
Generating icon metadata
metadata.json holds search tags for every icon, generated by a vision model
from the rendered icon and its name. Each entry also stores a hash of the
icon's SVG, so the generator only calls the model for icons that are new, have
changed, or have no tags yet; all other tags are reused. Entries for icons that
no longer exist are removed.
bun run check (and CI) fails when metadata.json is out of sync with
@canonical/ds-assets, so run the generator after bumping that package:
# Set OPENROUTER_API_KEY in your environment or ignored .env file.
bun run build:metadata
The generator accepts any endpoint supporting OpenAI-compatible Chat
Completions. The model must support image input. By default, it uses
OpenRouter with google/gemma-4-26b-a4b-it:
# Override the OpenRouter model.
bun run build:metadata --model google/gemini-3.1-flash-lite
For a custom endpoint, pass its API base URL and an explicit model:
# Ollama: start the server and download the chosen model beforehand.
bun run build:metadata --base-url http://localhost:11434/v1 --model gemma4:26b
# llama.cpp: start llama-server with your model; use its served model ID.
bun run build:metadata --base-url http://localhost:8080/v1 --model your-served-model-id
Custom endpoints use only METADATA_API_KEY when supplied, otherwise no
authentication header is sent.
Icons are processed 6 at a time by default; change this with --concurrency
(or -j), e.g. -j 1 for slow local servers. Requests time out after 120
seconds and are retried up to 2 times, with backoff, on timeouts, network
errors, rate limits, and server errors. Increase the timeout for slow local models with
--timeout <seconds>. Icons that still fail are reported at the end, the
remaining results are written, and the command exits with a non-zero status.
Each generated icon is logged on a single line with its tags. Add --verbose
(or -v) to also log the model's description of the drawing and its meaning.
Reused tags are normalized (lowercased, deduplicated, filler words removed).
Add --clean (or -c) to regenerate tags for all icons.