Skip to content

Getting Started

Installation

pip install kokage-ui
uv add kokage-ui

kokage-ui requires Python 3.11+ and installs FastAPI automatically.

Optional Dependencies

pip install kokage-ui[sql]       # SQLModel storage backend
pip install kokage-ui[markdown]  # Markdown rendering

CLI Scaffolding

The fastest way to start a new project:

kokage-ui init myapp
cd myapp
uv sync
uv run uvicorn app:app --reload

With CRUD template:

uvx kokage-ui init myapp --crud

Add pages and models to an existing project:

uvx kokage-ui add page dashboard      # Create pages/dashboard.py
uvx kokage-ui add crud Product        # Create models/product.py

Your First App

Create a file called app.py:

from fastapi import FastAPI
from kokage_ui import KokageUI, Page, Card, H1, P, DaisyButton

app = FastAPI()
ui = KokageUI(app)

@ui.page("/")
def home():
    return Page(
        Card(
            H1("Hello, kokage!"),
            P("Your first kokage-ui application."),
            actions=[DaisyButton("Get Started", color="primary")],
            title="Welcome",
        ),
        title="My First App",
    )

Run It

uvicorn app:app --reload
fastapi dev app.py

Open http://localhost:8000 in your browser.

How It Works

  1. KokageUI(app) — Wraps your FastAPI app. Mounts the bundled htmx.js and sets up static file serving.

  2. @ui.page("/") — Registers a route that returns a full HTML page. The decorated function should return a Page, Component, or str.

  3. Page(...) — Generates a complete <!DOCTYPE html> document with htmx and DaisyUI/Tailwind CSS automatically loaded via CDN.

  4. Card(...), H1(...), etc. — Python classes that render to HTML. Children are positional args, attributes are keyword args.

Adding Interactivity

Use @ui.fragment() for htmx partial responses:

from kokage_ui import Div, DaisyButton

@ui.page("/")
def home():
    return Page(
        Div(
            DaisyButton("Load Data", color="primary",
                        hx_get="/api/data", hx_target="#result"),
            Div(id="result"),
        ),
        title="Interactive App",
    )

@ui.fragment("/api/data")
def load_data():
    return Div("Data loaded via htmx!")

Clicking the button sends an htmx GET request to /api/data and inserts the response into #result.

Adding CRUD

Generate a full CRUD interface from a Pydantic model in one line:

from pydantic import BaseModel, Field
from kokage_ui import InMemoryStorage

class Todo(BaseModel):
    id: str = ""
    title: str = Field(min_length=1, max_length=200)
    completed: bool = False

storage = InMemoryStorage(Todo)

ui.crud("/todos", model=Todo, storage=storage)

This creates list, create, detail, edit, and delete pages at /todos.

For database persistence, use SQLModelStorage:

from kokage_ui import SQLModelStorage, create_tables

storage = SQLModelStorage(Todo, engine)

Next Steps