HTML-first, HTMX-powered components for Python-first apps
Greeble is an HTML-first component library for server-rendered Python apps. Each component ships with copy-and-paste markup, HTMX attributes, and CSS tokens so teams can build rich flows without a JavaScript bundler.
You can view the demo here. It is not connected to anything so it will not send emails or sign you up for anything. It is just a demo of the components.
- HTML first: Render everything on the server, enhance with HTMX or hyperscript when needed.
- Accessible by default: Components document roles, focus management, keyboard interaction, and ARIA contracts.
- Framework friendly: Works with Django, FastAPI, and Flask. Adapters expose helpers for partial rendering, HX headers, and CSRF handling.
- Own the source: The library copies snippets into your codebase so you can customise freely.
- Design tokens included:
greeble_coreprovides colour, spacing, and typography tokens plus utilitarian CSS helpers.
-
Install the package (PyPI release coming soon). Until then, install from the repo:
pip install git+https://github.com/bakobiibizo/greeble.git # or locally pip install -e .
-
Include the core CSS tokens in your base template. The tokens live at
packages/greeble_core/assets/css/greeble-core.css:<link rel="stylesheet" href="/static/greeble/greeble-core.css" />
-
Drop in component markup. Every component directory under
packages/greeble_components/components/<name>/templates/contains trigger markup and partials. Copy them into your templates or render them directly. -
Wire server endpoints. Components document the routes they expect. With FastAPI you can use the bundled adapter to serve full layouts or partial fragments:
from fastapi import FastAPI, Request from fastapi.templating import Jinja2Templates from greeble.adapters.fastapi import template_response app = FastAPI() templates = Jinja2Templates("templates") @app.get("/modal/example") async def modal_example(request: Request): return template_response( templates, "modal.html", context={}, request=request, partial_template="modal.partial.html", )
-
Return out-of-band updates when needed. Toasts and other shared UI ship with helper partials that set
hx-swap-oob="true"so a single response can update multiple regions.
See the component docs for contract details, events, and accessibility notes for each snippet.
Use the bundled CLI to scaffold projects and copy component files:
uv run greeble new ./apps/starter --include-docs # scaffold FastAPI starter project
uv run greeble list # view available components
uv run greeble list --json # machine-readable listing
uv run greeble add modal # copy modal templates/CSS into ./templates and ./static
uv run greeble add table --project ./apps/main --include-docs
uv run greeble sync modal --backup # re-copy modal, overwrite local edits with backups
uv run greeble remove table # remove previously copied files
uv run greeble doctor --project ./apps/main --json # sanity check manifest + project dirs (JSON)FastAPI is the default development target and is included in the dev group by default. If you want to experiment with Django or Flask adapters without installing their dependencies globally, enable the corresponding uv group on a per-command basis:
# Enable Django deps for a single command
uv run -G django dev check
# Enable Flask deps for a single command
uv run -G flask dev check
# Combine multiple groups if needed (FastAPI is already in dev)
uv run -G django -G flask dev test
# To sync a full environment once:
uv sync -G django # or: uv sync -G flaskThe adapters work even if you don’t install these extras; the helper modules import framework packages
inside function bodies so that importing greeble.adapters does not require Django/Flask.
Component commands (add, sync, remove) accept:
--project– destination root (default: current directory)--templates/--static– customise template/static roots (defaults:templates,static)--docs– customise documentation root (default:docs)--include-docs– copy or remove the component documentation page alongside markup/CSS--force– overwrite existing files duringadd--dry-run– preview copy/removal plans without writing
greeble new accepts --include-docs, --docs, --force, and --dry-run to control documentation copying, the docs root, overwriting existing files, and previewing the starter scaffold.
See docs/cli.md for a full walkthrough.
Spin up the landing demo to explore the full component slice:
uv run python examples/site/landing.pyThe demo mounts the core CSS, imports the latest component templates, and exposes HTMX endpoints for modals, drawers, tab content, table pagination, infinite lists, and toast queues.
| Component | Summary | Docs |
|---|---|---|
| Buttons | Primary, secondary, ghost, destructive, icon, loading variations | docs/components/button.md |
| Inputs | Text, email, select, textarea patterns with validation flow | docs/components/input.md |
| Modal | Dialog partial with backdrop, focus management, form example | docs/components/modal.md |
| Toasts | Out-of-band toast root and item fragments for global feedback | docs/components/toast.md |
| Table | Sortable, searchable table shell with server actions | docs/components/table.md |
| Drawer, Dropdown, Tabs, Stepper, Palette, Infinite List | See individual docs in docs/components/ |
— |
greeble.adapters.fastapi– HTMX-aware helpers for partial detection, HX trigger headers, and template rendering.- Placeholders exist for Django and Flask adapters; contributions are welcome to bring those to parity with the FastAPI implementation.
- See docs/adapters.md for quick-start patterns with the CLI.
packages/
greeble_core/ # Shared CSS tokens and utilities
greeble_components/ # Component markup, CSS, and docs
adapters/ # Framework-specific helpers
examples/ # Demo apps (FastAPI, Django, Flask) and landing flow
src/greeble/ # Installable Python package surface
- See the living roadmap in docs/roadmap.md.
- Track current progress in docs/progress.md.
- Fork the repo and create a branch.
- Run the demo and tests locally:
uv run dev test. - Submit a pull request that includes documentation updates for new components or behaviours.
MIT License © 2025 Greeble contributors.