Skip to main content

citry-phosphor-icons

Phosphor Icons as citry components.

Browse all icons →

Install

pip install citry-phosphor-icons

The library configures itself through a citry extension, so install both:

import citry_phosphor_icons
from citry import Citry
from citry_phosphor_icons import PhosphorIcons

app = Citry(extensions=[PhosphorIcons])
app.register_library(citry_phosphor_icons)

Registration fails with a clear error if the extension is missing, so the two cannot drift apart.

Naming the tag

The component is <c-icon />. To publish it under a different tag, install the manifest that library() builds:

app.register_library(citry_phosphor_icons.library("ph-icon"))

That gives <c-ph-icon /> and nothing else. A manifest owns the names it publishes and citry will not retire one, so this replaces the default rather than adding to it - install either this package or a named manifest, not both.

To keep <c-icon /> and answer to a second name as well, alias the installed class instead:

from citry_phosphor_icons import Icon

installed = app.register_library(citry_phosphor_icons)
app.register(installed.component(Icon), "ph-icon")

Use

<c-icon name="house" />
<c-icon name="house" weight="bold" />
<c-icon name="house" style="stroke" c-size="24" color="#ff0000" />
Kwarg Type Default Description
name str — Icon name, e.g. "house"
weight str engine default bold, duotone, fill, light, regular, thin
style str engine default flat or stroke
size str or int None Sets width and height; any CSS length ("1.5rem"), an int is read as px
color str None Sets CSS color
mirrored bool False Flips the icon horizontally
attrs dict None Extra attributes passed to the <svg> element

class and style from attrs are combined with the component's own, not replaced by them - so passing c-attrs="{'class': 'me-2'}" keeps whatever the component already sets, and size still wins over a conflicting width.

Settings

Defaults belong to the engine, not the process, so two Citry instances can differ:

app = Citry(
    extensions=[PhosphorIcons],
    extensions_defaults={"phosphor": {"default_weight": "bold", "default_style": "stroke"}},
)

A caller's keyword argument beats the engine default, and a component may pin its own. Because a library definition cannot carry engine-specific fields, pin it on the installed class:

installed = app.register_library(citry_phosphor_icons)


class ThinIcon(installed.component(Icon)):
    class Phosphor:
        default_weight = "thin"

Unknown fields and invalid values are rejected when the engine is built, not at the first render.

Rendering is cached per unique set of keyword arguments. Citry reads Cache.enabled as a literal on the component class, so turning it off is a property of the manifest rather than an engine setting:

app.register_library(citry_phosphor_icons.library(cache=False))

Subclassing

Kwargs is inherited, so a subclass only declares what it changes. get_attrs() returns what the component sets on the <svg> itself, get_default_attrs() what the caller's attrs may override. Subclass the definition and ship it as your own library:

from citry import ComponentLibrary, merge_attrs
from citry_phosphor_icons import Icon


class MyIcon(Icon):
    def get_attrs(self, kwargs):
        return merge_attrs({"class": "icon"}, super().get_attrs(kwargs))


__citry_library__ = ComponentLibrary(
    name="my-icons",
    components=(MyIcon,),
    required_extensions=("phosphor",),
)

Previews

The component ships examples for citry's preview extension: one per weight and style, plus the presentation arguments. preview_app.py in this repository wires an engine for it:

uv run citry --app preview_app:app ext run preview serve

Open the printed gallery URL. Variants are plain keyword arguments rather than a preview template, so they keep working under a different tag name.

An icon carries no width or height of its own - it takes the size of its surroundings, like a letter does. Every variant therefore asks for a size, and the preview frame is only a little larger.

The gallery documents the component. For the icon set itself, browse the catalogue in py-phosphor-icons, which has search, a size slider and a colour picker across all 1512 icons in every weight and style.

Search and metadata

The icons, the loader and search over the icon metadata live in py-phosphor-icons, which this package builds on:

from py_phosphor_icons import get_svg, get_svg_inner, icon_names, search_icons

search_icons("arrow left")  # ranked, best match first
search_icons("roledex")  # matches on tags: address-book
get_svg("house", weight="bold")

The same search answers a wrong name, so <c-icon name="cart" /> raises Did you mean: shopping-cart, shopping-cart-simple, car?, narrowed to icons that exist in the requested weight and style.

Development

uv sync
uv run pytest
uv run ruff check .
uv run ruff format .

The icon set and its metadata are maintained in py-phosphor-icons; the sync scripts live there.

Known icon issues

A few icons are incomplete in the upstream Phosphor release and fail to render in certain weight and style combinations. The current list is maintained in py-phosphor-icons, which is where the icon set is synced.

Metadata

Release files for citry-phosphor-icons 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for citry-phosphor-icons 0.1.0
File Size Uploaded
citry_phosphor_icons-0.1.0.tar.gz 46.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for citry-phosphor-icons 0.1.0
File Interpreter ABI Platform
citry_phosphor_icons-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 55.8 kB

Release files / citry_phosphor_icons-0.1.0.tar.gz

Download URL citry_phosphor_icons-0.1.0.tar.gz
Size 46.9 kB
Tags Source
SHA-256 checksum
How to use checksums
41cf69801c744cadc5ceaec6682e00a6311fb1231255db6d8aef5591fee84314
BLAKE2b-256 checksum
How to use checksums
5f607d375eec316fd1311b769781f4e1f993a06464c25b9c2aceb38df40a1ddd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release files / citry_phosphor_icons-0.1.0-py3-none-any.whl

Download URL citry_phosphor_icons-0.1.0-py3-none-any.whl
Size 8.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
90462ce730acc095e6f95e2dfe1418425b10c5584bf8f1030e07b1ec56f81a61
BLAKE2b-256 checksum
How to use checksums
2cdcaa88032aa03bbf1d3aa749440888ae81d61d4efbf4dd2f46d44a9b61afe1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page