{"id":44990238,"url":"https://github.com/lbliii/chirp-ui","last_synced_at":"2026-05-14T15:01:33.875Z","repository":{"id":339240370,"uuid":"1161003772","full_name":"lbliii/chirp-ui","owner":"lbliii","description":"UI Library for Chirp","archived":false,"fork":false,"pushed_at":"2026-05-11T00:13:21.000Z","size":9311,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T01:26:44.836Z","etag":null,"topics":["alpinejs","component-library","css-components","htmx","jinja2","no-build","python","ssr","ui-components"],"latest_commit_sha":null,"homepage":"https://lbliii.github.io/chirp-ui/","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lbliii.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":".github/AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-18T16:14:32.000Z","updated_at":"2026-05-11T00:13:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lbliii/chirp-ui","commit_stats":null,"previous_names":["lbliii/chirp-ui"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/lbliii/chirp-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fchirp-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fchirp-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fchirp-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fchirp-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lbliii","download_url":"https://codeload.github.com/lbliii/chirp-ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fchirp-ui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33030380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alpinejs","component-library","css-components","htmx","jinja2","no-build","python","ssr","ui-components"],"created_at":"2026-02-18T21:16:54.340Z","updated_at":"2026-05-14T15:01:33.868Z","avatar_url":"https://github.com/lbliii.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ʘ chirp-ui\n\n[![PyPI version](https://img.shields.io/pypi/v/chirp-ui.svg)](https://pypi.org/project/chirp-ui/)\n[![Tests](https://github.com/lbliii/chirp-ui/actions/workflows/tests.yml/badge.svg)](https://github.com/lbliii/chirp-ui/actions/workflows/tests.yml)\n[![Python 3.14+](https://img.shields.io/badge/python-3.14+-blue.svg)](https://pypi.org/project/chirp-ui/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Status: Alpha](https://img.shields.io/badge/status-alpha-orange.svg)](https://pypi.org/project/chirp-ui/)\n\n**Python-native UI components for Chirp and Kida apps.**\n\nchirp-ui gives server-rendered Python apps a real component vocabulary:\nKida macros, typed variants and sizes, registry-cited CSS classes, design\ntokens, htmx/Alpine interaction patterns, and an agent-groundable manifest.\nNo Node pipeline. No utility-class vocabulary. No mystery CSS strings that\nyour Python tests and tools cannot see.\n\n## Quick Start\n\n```bash\npip install chirp chirp-ui\n```\n\n```python\nfrom chirp import App, AppConfig, use_chirp_ui\n\napp = App(AppConfig(template_dir=\"templates\", debug=True))\nuse_chirp_ui(app, prefix=\"/static\")\n```\n\n```kida\n{% from \"chirpui/layout.html\" import container, grid, block %}\n{% from \"chirpui/card.html\" import card %}\n{% from \"chirpui/button.html\" import btn %}\n\n{% call container() %}\n  {% call grid(cols=2) %}\n    {% call block() %}\n      {% call card(title=\"Pipeline\", subtitle=\"Live status\") %}\n        \u003cp\u003eBuilds, deploys, and background jobs in one swappable panel.\u003c/p\u003e\n        {{ btn(\"View details\", href=\"/pipeline\", variant=\"primary\") }}\n      {% endcall %}\n    {% endcall %}\n    {% call block() %}\n      {% call card(title=\"Queue\", subtitle=\"7 jobs waiting\") %}\n        \u003cp\u003eRendered on the server, ready for htmx refreshes.\u003c/p\u003e\n      {% endcall %}\n    {% endcall %}\n  {% endcall %}\n{% endcall %}\n```\n\nWhen you use Chirp, `use_chirp_ui(app)` registers the template loader, filters,\nstatic assets, debug-aware strict validation, Alpine runtime support, and\nChirp-aware link/swap helpers. For standalone Kida usage, use\n`chirp_ui.get_loader()` and serve the files from `chirp_ui.static_path()`.\n\n## What It Is\n\nchirp-ui is the optional companion design system for\n[Chirp](https://github.com/lbliii/chirp), built on\n[Kida](https://github.com/lbliii/kida). It is not the framework itself. It is\none opinionated way to build Chirp apps with a polished default UI, predictable\nHTMX behavior, and components that stay inspectable from Python.\n\nThe central idea is simple: the component registry is the source of truth.\nMacros, CSS, docs, validation, and the shipped manifest are projections of that\nregistry.\n\n## Use chirp-ui For\n\n| Surface | What chirp-ui gives you |\n|---|---|\n| Chirp apps | App shells, navigation, cards, forms, overlays, dashboard panels, and htmx-safe patterns |\n| Admin screens | Fragment islands, confirm flows, polling, row actions, inline edit controls, and status displays |\n| Data-heavy pages | Tables, pagination, metrics, timelines, trees, charts, descriptions, and resource indexes |\n| Streaming UIs | SSE status, streaming blocks, copy buttons, model cards, suspense states, and retry affordances |\n| Documentation | Page heroes, nav trees, params tables, signatures, code blocks, and index cards |\n| Coding agents | `chirp_ui.manifest.build_manifest()` with real components, slots, params, classes, and tokens |\n\n## Component Vocabulary\n\nchirp-ui ships more than 300 registry-described components and primitives.\n\n| Family | Examples |\n|---|---|\n| Layout | `container`, `stack`, `cluster`, `grid`, `frame`, `block`, `split_layout`, `app_shell`, `workspace_shell` |\n| Controls | `btn`, `icon_btn`, `button_group`, `segmented_control`, `row_actions`, `theme_toggle`, `copy_btn` |\n| Feedback | `alert`, `badge`, `toast`, `spinner`, `skeleton`, `progress`, `empty_state`, `callout` |\n| Forms | `text_field`, `select_field`, `checkbox_field`, `toggle_field`, `file_field`, `date_field`, `wizard_form` |\n| Navigation | `tabs`, `route_tabs`, `breadcrumbs`, `navbar`, `sidebar`, `nav_tree`, `pagination`, `stepper` |\n| Data display | `table`, `metric_card`, `stat`, `timeline`, `tree_view`, `calendar`, `avatar`, `description_list` |\n| Overlays | `modal`, `drawer`, `tray`, `popover`, `tooltip`, `command_palette` |\n| Effects and ASCII | `shimmer_button`, `glow_card`, `aurora`, `ascii_card`, `ascii_table`, `ascii_spinner` |\n\nComposition primitives are macros, not utilities. Reach for `stack()`,\n`cluster()`, `grid()`, `frame()`, and `block()` instead of inventing spacing or\ndisplay classes.\n\n## Registry And Manifest\n\nThe registry in `chirp_ui.components.COMPONENTS` describes every public block:\nvariants, sizes, modifiers, BEM elements, slots, composed children, emitted\nclasses, tokens, maturity, authoring hints, and runtime requirements.\n\n```python\nfrom chirp_ui import load_manifest\nfrom chirp_ui.components import design_system_report\n\nmanifest = load_manifest()\ncard = manifest[\"components\"][\"card\"]\nprint(card[\"params\"])\nprint(card[\"slots\"])\n\nreport = design_system_report()\nprint(report[\"stats\"][\"total_components\"])  # 309\n```\n\nThe shipped manifest schema is `chirpui-manifest@5`. It is available as:\n\n| Surface | How to read it |\n|---|---|\n| Python API | `chirp_ui.load_manifest()` or `chirp_ui.manifest.build_manifest()` |\n| CLI | `python -m chirp_ui.manifest --json` |\n| Package data | `chirp_ui.MANIFEST_PATH` |\n| Docs build | `site/public/chirpui.manifest.json` from `poe docs-build-all` |\n\nThis is the agent contract: downstream tools should cite the manifest instead\nof guessing component names, slots, variants, or CSS classes.\n\n## Framework Integration Metadata\n\nFrameworks and static-site generators should use Chirp UI's package contract\ninstead of hardcoding shipped asset names or filesystem paths:\n\n```python\nimport chirp_ui\n\ncontract = chirp_ui.get_library_contract()\n\nprint(contract.static_root)\nprint([asset.path for asset in contract.css])\nprint([asset.path for asset in contract.js])\nprint([pack.path for pack in contract.theme_packs])\n```\n\nThe contract is framework-neutral. It describes the template package/path,\nstatic root, manifest path/schema, ordered CSS entries, ordered JS entries, and\noptional runtime assets. It also lists packaged token-only theme packs under\n`contract.theme_packs`. Hosts still own how those assets are bundled, linked,\nfingerprinted, and served.\n\n## CSS Contract\n\nchirp-ui CSS is generated from partials and guarded by registry parity tests.\nEvery shipped `chirpui-*` class must be cited by a registry entry, defined in\nCSS, and reachable from the templates that emit it.\n\nThe cascade order is public API:\n\n```css\n@layer chirpui.reset, chirpui.token, chirpui.base, chirpui.component, chirpui.utility, app.overrides;\n```\n\nPut application overrides in `app.overrides` and use `--chirpui-*` custom\nproperties for theming. Do not fight the design system with specificity.\n\n```css\n:root {\n  --chirpui-accent: #2563eb;\n  --chirpui-container-max: 80rem;\n  --chirpui-radius-lg: 0.75rem;\n}\n\n@layer app.overrides {\n  .billing-panel {\n    --chirpui-card-hover-border: color-mix(in oklab, var(--chirpui-accent) 35%, var(--chirpui-border));\n  }\n}\n```\n\nFresh apps should start with a token-only app theme layer loaded after\n`chirpui.css`. Chirp-UI ships a starter at\n`/static/themes/app-theme-starter.css`, plus curated catalog packs at\n`/static/themes/atlas.css`, `/static/themes/ember.css`, and\n`/static/themes/sage.css`; each covers light, dark, and `system` mode so\n`theme_toggle()` has coherent app-owned tokens immediately. The runnable\ncomponent showcase includes a `/theme-packs` matrix for visual comparison.\n\nFor token and override details, see\n[APP-THEME.md](docs/APP-THEME.md),\n[TOKENS.md](docs/TOKENS.md),\n[CSS-OVERRIDE-SURFACE.md](docs/CSS-OVERRIDE-SURFACE.md), and\n[COMPONENT-OPTIONS.md](docs/COMPONENT-OPTIONS.md).\n\nHigh-traffic components also support descriptor-backed visual presets through\nmacro parameters such as `appearance=\"outlined\"` and `tone=\"danger\"`.\nUse these instead of hand-written preset classes. See\n[APPEARANCE-TONE.md](docs/APPEARANCE-TONE.md) for the pilot vocabulary and\nmigration map.\n\n## Interactivity\n\nchirp-ui stays server-rendered by default. Interactive components are htmx- and\nAlpine-native where browser state is the right tool.\n\n| Pattern | Components and docs |\n|---|---|\n| HTMX fragments | `fragment_island`, `poll_trigger`, `oob`, `infinite_scroll`, [HTMX-PATTERNS.md](docs/HTMX-PATTERNS.md) |\n| Alpine behavior | `dropdown`, `modal`, `tray`, `tabs`, `theme_toggle`, `copy_btn`, [ALPINE-MAGICS.md](docs/ALPINE-MAGICS.md) |\n| App shell swaps | `app_shell`, `shell_frame`, `route_tabs`, [SHELL-TABS-CONTRACT.md](docs/SHELL-TABS-CONTRACT.md) |\n| High-state islands | `island_root`, `grid_state`, `wizard_state`, `upload_state`, [DND-FRAGMENT-ISLAND.md](docs/DND-FRAGMENT-ISLAND.md) |\n| Streaming | `streaming_block`, `sse_status`, `model_card`, `copy_btn`, [HTMX-ADVANCEMENT.md](docs/HTMX-ADVANCEMENT.md) |\n\nNamed Alpine controllers live in `chirpui-alpine.js` and register through\n`Alpine.safeData()`, so htmx swaps can initialize behavior safely. Component\ntemplates do not ship inline `\u003cscript\u003e` tags.\n\n## Standalone Kida\n\nYou can use chirp-ui without Chirp by adding its loader to a Kida environment.\n\n```python\nfrom kida import ChoiceLoader, Environment, FileSystemLoader\nfrom chirp_ui import get_loader\n\nenv = Environment(\n    loader=ChoiceLoader([\n        FileSystemLoader(\"templates\"),\n        get_loader(),\n    ])\n)\n```\n\nIn standalone setups, register equivalent filters/globals and serve\n`chirpui.css`, `chirpui.js`, `chirpui-alpine.js`, themes, and pattern assets\nfrom `chirp_ui.static_path()`.\n\n## Requirements\n\n| Package | Requirement |\n|---|---|\n| Python | `\u003e=3.14` |\n| Kida | `kida-templates\u003e=0.9.0` |\n| Chirp | Optional, but recommended for `use_chirp_ui(app)` |\n| Browser JS | Alpine 3.x for interactive components; auto-injected by Chirp integration |\n\nchirp-ui declares free-threading support and avoids build/runtime dependencies\nthat rely on the GIL. The build pipeline is Python-native and CSS is assembled\nfrom package partials.\n\n## Showcase\n\n```bash\ngit clone https://github.com/lbliii/chirp-ui.git\ncd chirp-ui\npip install -e \".[showcase]\"\npython examples/component-showcase/app.py\n```\n\nThen open \u003chttp://localhost:8000\u003e.\n\nWith the b-stack workspace:\n\n```bash\ncd /path/to/b-stack\nuv sync\nuv run python chirp-ui/examples/component-showcase/app.py\n```\n\n## Development\n\n```bash\ngit clone https://github.com/lbliii/chirp-ui.git\ncd chirp-ui\nuv sync --group dev\nuv run poe ci\n```\n\n| Task | Command |\n|---|---|\n| Run tests | `uv run pytest` or `uv run poe test` |\n| Type check | `uv run ty check src/chirp_ui/` or `uv run poe ty` |\n| Lint | `uv run ruff check .` or `uv run poe lint` |\n| Build CSS | `uv run poe build-css` |\n| Check manifest | `uv run poe build-manifest-check` |\n| Full CI | `uv run poe ci` |\n| Docs site and showcase | `uv sync --group docs` then `uv run poe docs-build-all` |\n\nIf you edit CSS, change `src/chirp_ui/templates/css/partials/*.css`, run\n`uv run poe build-css`, and commit the generated `chirpui.css`.\n\nIf you edit a macro's public surface, update the registry entry and regenerate\nthe manifest/docs projections.\n\n## Status\n\nchirp-ui is pre-1.0 and shipped. Core principles are stable: Python-native\ncomponents, registry-cited CSS, no utility vocabulary, htmx/Alpine defaults,\nand free-threading-ready tooling. Some variants, experimental effects, and\nlegacy compatibility classes can still move before 1.0.\n\n## The Bengal Ecosystem\n\nchirp-ui is part of a pure-Python stack built for Python 3.14t free-threading.\n\n| | | | |\n|--:|---|---|---|\n| **ᓚᘏᗢ** | [Bengal](https://github.com/lbliii/bengal) | Static site generator | [Docs](https://lbliii.github.io/bengal/) |\n| **∿∿** | [Purr](https://github.com/lbliii/purr) | Content runtime | - |\n| **⌁⌁** | [Chirp](https://github.com/lbliii/chirp) | Web framework | [Docs](https://lbliii.github.io/chirp/) |\n| **ʘ** | **chirp-ui** | Python-native UI components | [Docs](https://lbliii.github.io/chirp-ui/) |\n| **=^..^=** | [Pounce](https://github.com/lbliii/pounce) | ASGI server | [Docs](https://lbliii.github.io/pounce/) |\n| **)彡** | [Kida](https://github.com/lbliii/kida) | Component template engine | [Docs](https://lbliii.github.io/kida/) |\n| **ฅᨐฅ** | [Patitas](https://github.com/lbliii/patitas) | Markdown parser | [Docs](https://lbliii.github.io/patitas/) |\n| **⌾⌾⌾** | [Rosettes](https://github.com/lbliii/rosettes) | Syntax highlighter | [Docs](https://lbliii.github.io/rosettes/) |\n| **ᓃ‿ᓃ** | [Milo](https://github.com/lbliii/milo-cli) | Terminal UI framework | [Docs](https://lbliii.github.io/milo-cli/) |\n\nPython-native. Free-threading ready. No npm required.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flbliii%2Fchirp-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flbliii%2Fchirp-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flbliii%2Fchirp-ui/lists"}