Skip to content

lbliii/chirp-ui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

258 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ʘ chirp-ui

PyPI version Tests Python 3.14+ License: MIT Status: Alpha

Python-native UI components for Chirp and Kida apps.

chirp-ui gives server-rendered Python apps a real component vocabulary: Kida macros, typed variants and sizes, registry-cited CSS classes, design tokens, htmx/Alpine interaction patterns, and an agent-groundable manifest. No Node pipeline. No utility-class vocabulary. No mystery CSS strings that your Python tests and tools cannot see.

Quick Start

pip install chirp chirp-ui
from chirp import App, AppConfig, use_chirp_ui

app = App(AppConfig(template_dir="templates", debug=True))
use_chirp_ui(app, prefix="/static")
{% from "chirpui/layout.html" import container, grid, block %}
{% from "chirpui/card.html" import card %}
{% from "chirpui/button.html" import btn %}

{% call container() %}
  {% call grid(cols=2) %}
    {% call block() %}
      {% call card(title="Pipeline", subtitle="Live status") %}
        <p>Builds, deploys, and background jobs in one swappable panel.</p>
        {{ btn("View details", href="/pipeline", variant="primary") }}
      {% endcall %}
    {% endcall %}
    {% call block() %}
      {% call card(title="Queue", subtitle="7 jobs waiting") %}
        <p>Rendered on the server, ready for htmx refreshes.</p>
      {% endcall %}
    {% endcall %}
  {% endcall %}
{% endcall %}

When you use Chirp, use_chirp_ui(app) registers the template loader, filters, static assets, debug-aware strict validation, Alpine runtime support, and Chirp-aware link/swap helpers. For standalone Kida usage, use chirp_ui.get_loader() and serve the files from chirp_ui.static_path().

What It Is

chirp-ui is the optional companion design system for Chirp, built on Kida. It is not the framework itself. It is one opinionated way to build Chirp apps with a polished default UI, predictable HTMX behavior, and components that stay inspectable from Python.

The central idea is simple: the component registry is the source of truth. Macros, CSS, docs, validation, and the shipped manifest are projections of that registry.

Use chirp-ui For

Surface What chirp-ui gives you
Chirp apps App shells, navigation, cards, forms, overlays, dashboard panels, and htmx-safe patterns
Admin screens Fragment islands, confirm flows, polling, row actions, inline edit controls, and status displays
Data-heavy pages Tables, pagination, metrics, timelines, trees, charts, descriptions, and resource indexes
Streaming UIs SSE status, streaming blocks, copy buttons, model cards, suspense states, and retry affordances
Documentation Page heroes, nav trees, params tables, signatures, code blocks, and index cards
Coding agents chirp_ui.manifest.build_manifest() with real components, slots, params, classes, and tokens

Component Vocabulary

chirp-ui ships more than 300 registry-described components and primitives.

Family Examples
Layout container, stack, cluster, grid, frame, block, split_layout, app_shell, workspace_shell
Controls btn, icon_btn, button_group, segmented_control, row_actions, theme_toggle, copy_btn
Feedback alert, badge, toast, spinner, skeleton, progress, empty_state, callout
Forms text_field, select_field, checkbox_field, toggle_field, file_field, date_field, wizard_form
Navigation tabs, route_tabs, breadcrumbs, navbar, sidebar, nav_tree, pagination, stepper
Data display table, metric_card, stat, timeline, tree_view, calendar, avatar, description_list
Overlays modal, drawer, tray, popover, tooltip, command_palette
Effects and ASCII shimmer_button, glow_card, aurora, ascii_card, ascii_table, ascii_spinner

Composition primitives are macros, not utilities. Reach for stack(), cluster(), grid(), frame(), and block() instead of inventing spacing or display classes.

Registry And Manifest

The registry in chirp_ui.components.COMPONENTS describes every public block: variants, sizes, modifiers, BEM elements, slots, composed children, emitted classes, tokens, maturity, authoring hints, and runtime requirements.

from chirp_ui import load_manifest
from chirp_ui.components import design_system_report

manifest = load_manifest()
card = manifest["components"]["card"]
print(card["params"])
print(card["slots"])

report = design_system_report()
print(report["stats"]["total_components"])  # 309

The shipped manifest schema is chirpui-manifest@5. It is available as:

Surface How to read it
Python API chirp_ui.load_manifest() or chirp_ui.manifest.build_manifest()
CLI python -m chirp_ui.manifest --json
Package data chirp_ui.MANIFEST_PATH
Docs build site/public/chirpui.manifest.json from poe docs-build-all

This is the agent contract: downstream tools should cite the manifest instead of guessing component names, slots, variants, or CSS classes.

Framework Integration Metadata

Frameworks and static-site generators should use Chirp UI's package contract instead of hardcoding shipped asset names or filesystem paths:

import chirp_ui

contract = chirp_ui.get_library_contract()

print(contract.static_root)
print([asset.path for asset in contract.css])
print([asset.path for asset in contract.js])
print([pack.path for pack in contract.theme_packs])

The contract is framework-neutral. It describes the template package/path, static root, manifest path/schema, ordered CSS entries, ordered JS entries, and optional runtime assets. It also lists packaged token-only theme packs under contract.theme_packs. Hosts still own how those assets are bundled, linked, fingerprinted, and served.

CSS Contract

chirp-ui CSS is generated from partials and guarded by registry parity tests. Every shipped chirpui-* class must be cited by a registry entry, defined in CSS, and reachable from the templates that emit it.

The cascade order is public API:

@layer chirpui.reset, chirpui.token, chirpui.base, chirpui.component, chirpui.utility, app.overrides;

Put application overrides in app.overrides and use --chirpui-* custom properties for theming. Do not fight the design system with specificity.

:root {
  --chirpui-accent: #2563eb;
  --chirpui-container-max: 80rem;
  --chirpui-radius-lg: 0.75rem;
}

@layer app.overrides {
  .billing-panel {
    --chirpui-card-hover-border: color-mix(in oklab, var(--chirpui-accent) 35%, var(--chirpui-border));
  }
}

Fresh apps should start with a token-only app theme layer loaded after chirpui.css. Chirp-UI ships a starter at /static/themes/app-theme-starter.css, plus curated catalog packs at /static/themes/atlas.css, /static/themes/ember.css, and /static/themes/sage.css; each covers light, dark, and system mode so theme_toggle() has coherent app-owned tokens immediately. The live component showcase includes a /theme-packs matrix for visual comparison.

For token and override details, see APP-THEME.md, TOKENS.md, CSS-OVERRIDE-SURFACE.md, and COMPONENT-OPTIONS.md.

High-traffic components also support descriptor-backed visual presets through macro parameters such as appearance="outlined" and tone="danger". Use these instead of hand-written preset classes. See APPEARANCE-TONE.md for the pilot vocabulary and migration map.

Interactivity

chirp-ui stays server-rendered by default. Interactive components are htmx- and Alpine-native where browser state is the right tool.

Pattern Components and docs
HTMX fragments fragment_island, poll_trigger, oob, infinite_scroll, HTMX-PATTERNS.md
Alpine behavior dropdown, modal, tray, tabs, theme_toggle, copy_btn, ALPINE-MAGICS.md
App shell swaps app_shell, shell_frame, route_tabs, SHELL-TABS-CONTRACT.md
High-state islands island_root, grid_state, wizard_state, upload_state, DND-FRAGMENT-ISLAND.md
Streaming streaming_block, sse_status, model_card, copy_btn, HTMX-ADVANCEMENT.md

Named Alpine controllers live in chirpui-alpine.js and register through Alpine.safeData(), so htmx swaps can initialize behavior safely. Component templates do not ship inline <script> tags.

Standalone Kida

You can use chirp-ui without Chirp by adding its loader to a Kida environment.

from kida import ChoiceLoader, Environment, FileSystemLoader
from chirp_ui import get_loader

env = Environment(
    loader=ChoiceLoader([
        FileSystemLoader("templates"),
        get_loader(),
    ])
)

In standalone setups, register equivalent filters/globals and serve chirpui.css, chirpui.js, chirpui-alpine.js, themes, and pattern assets from chirp_ui.static_path().

Bengal Theme (chirp-theme)

The same package ships chirp-theme, a static-first Bengal theme that puts the chirp-ui design language on documentation and marketing sites. Installing chirp-ui registers the theme through the bengal.themes entry point — no separate install — and you adopt it by pointing your site config at it:

# config/_default/theme.yaml  (or the theme block in bengal.toml)
theme:
  name: "chirp-theme"
uv run bengal build
uv run bengal serve

chirp-theme requires Bengal >=0.3.3, whose library_asset_tags() hook links the bundled chirpui.css. On older Bengal the base CSS is silently dropped and layouts collapse.

Full adoption quickstart: Apply chirp-theme to a Bengal site and the chirp-theme reference.

Requirements

Package Requirement
Python >=3.14
Kida kida-templates>=0.9.0
Chirp Optional, but recommended for use_chirp_ui(app)
Browser JS Alpine 3.x for interactive components; auto-injected by Chirp integration

chirp-ui declares free-threading support and avoids build/runtime dependencies that rely on the GIL. The build pipeline is Python-native and CSS is assembled from package partials.

Showcase

The live, interactive showcase runs the real examples/component-showcase Chirp app — every macro, shell, form, island, and streaming demo against a real server runtime:

https://chirp-ui-showcase-production.up.railway.app

Or run it locally:

git clone https://github.com/lbliii/chirp-ui.git
cd chirp-ui
pip install -e ".[showcase]"
python examples/component-showcase/app.py

Then open http://localhost:8000.

With the b-stack workspace:

cd /path/to/b-stack
uv sync
uv run python chirp-ui/examples/component-showcase/app.py

Development

git clone https://github.com/lbliii/chirp-ui.git
cd chirp-ui
uv sync --group dev
uv run poe ci
Task Command
Run tests uv run pytest or uv run poe test
Type check uv run ty check src/chirp_ui/ or uv run poe ty
Lint uv run ruff check . or uv run poe lint
Build CSS uv run poe build-css
Check manifest uv run poe build-manifest-check
Full CI uv run poe ci
Docs site uv sync --group docs then uv run poe docs-build-all

If you edit CSS, change src/chirp_ui/templates/css/partials/*.css, run uv run poe build-css, and commit the generated chirpui.css.

If you edit a macro's public surface, update the registry entry and regenerate the manifest/docs projections.

Status

chirp-ui is pre-1.0 and shipped. Core principles are stable: Python-native components, registry-cited CSS, no utility vocabulary, htmx/Alpine defaults, and free-threading-ready tooling. Some variants, experimental effects, and legacy compatibility classes can still move before 1.0.

The Bengal Ecosystem

chirp-ui is part of a pure-Python stack built for Python 3.14t free-threading.

ᓚᘏᗢ Bengal Static site generator Docs
∿∿ Purr Content runtime -
⌁⌁ Chirp Web framework Docs
ʘ chirp-ui Python-native UI components Docs
=^..^= Pounce ASGI server Docs
)彡 Kida Component template engine Docs
ฅᨐฅ Patitas Markdown parser Docs
⌾⌾⌾ Rosettes Syntax highlighter Docs
ᓃ‿ᓃ Milo Terminal UI framework Docs

Python-native. Free-threading ready. No npm required.

License

MIT