### Install StarHTML Source: https://github.com/banditburai/starhtml/blob/main/README.md Install the StarHTML package using pip. ```bash pip install starhtml ``` -------------------------------- ### Clone and Set Up StarHTML Repository Source: https://github.com/banditburai/starhtml/blob/main/README.md Clone the StarHTML repository and install development dependencies using `uv` or `pip`. ```bash git clone https://github.com/banditburai/starhtml.git cd starhtml uv sync # or pip install -e ".[dev]" pytest && ruff check . ``` -------------------------------- ### Timeline Tab Setup Script Source: https://github.com/banditburai/starhtml/blob/main/docs/plans/2026-02-17-debugger-timeline-tab.md Includes a setup script section that imports the debugger timeline JavaScript, initializes it, subscribes to updates, and schedules renders using requestAnimationFrame. It also handles active tab switching for performance. ```javascript Add setup script section that imports `debugger-timeline.js`, calls `init()`, subscribes to updates, and schedules renders via `requestAnimationFrame`. ``` ```javascript Wire active tab switching: only render timeline when tab is active (performance, same pattern as other tabs). ``` -------------------------------- ### Add Route/URL to Start Event Preview Source: https://github.com/banditburai/starhtml/blob/main/docs/plans/2026-02-15-debugger-phase-1.5.md Includes the route or URL associated with a 'start' event in its preview. This information is typically derived from an attribute like `data-on-click` on the triggering element. ```string Add the route/URL to the `start` event preview (from the element's `data-on-click` or similar attribute). ``` -------------------------------- ### Send GET Request with @get() Source: https://github.com/banditburai/starhtml/blob/main/DATASTAR_REFERENCE.md Initiate a GET request using the Fetch API. By default, it includes Datastar headers and query parameters derived from signals. Configure options like `openWhenHidden` or `contentType` for specific behaviors. ```html ``` ```html ``` ```html ``` ```html
``` -------------------------------- ### Register Startup and Shutdown Handlers (Constructor Lists) Source: https://github.com/banditburai/starhtml/blob/main/API.md Register startup and shutdown handlers using constructor lists for quick setup. Handlers can be sync or async and optionally accept the app instance. ```python app, rt = star_app( on_startup=[init_db, warm_cache], on_shutdown=[close_db], ) ``` -------------------------------- ### Make HTTP Requests with get(), post(), delete() Source: https://github.com/banditburai/starhtml/blob/main/API.md Use HTTP methods like get(), post(), and delete() to make requests from the browser. By default, all signals are sent as the request body. Use the `payload` option to send specific data. ```python # All signal values are sent automatically — no need to specify data data_on_click=get("/api/data") data_on_click=post("/api/submit") data_on_click=delete(f"/api/items/{item_id}") # item_id is a Python variable baked into the URL at render time ``` ```python # Conditional requests data_on_click=is_valid.then(post("/api/submit")) ``` ```python # Send only "text" — derived from a browser-side DOM value data_on_blur=post("/api/edit", payload={"text": js("evt.target.innerText.trim()")}) ``` ```python # Set content type for form submissions data_on_click=post("/api/submit", contentType="form") ``` ```python # Send only signals whose names match a regex data_on_click=post("/api/submit", filterSignals="name|email") ``` -------------------------------- ### WebSocket Support in StarHTML Source: https://context7.com/banditburai/starhtml/llms.txt Integrate real-time bidirectional communication using WebSocket endpoints. Use `setup_ws(app)` to get a broadcast function and define custom handlers with `@app.ws()`. ```python from starhtml import * app, rt = star_app() send = setup_ws(app) # Returns broadcast function # Custom WebSocket handler @app.ws("/chat") async def chat_handler(ws, data, send): # data contains parsed JSON from client message = data.get("message", "") await send(Div(f"Echo: {message}", id="output")) # With connection lifecycle @app.ws("/live", conn=on_connect, disconn=on_disconnect) async def live_handler(ws, data): pass async def on_connect(ws): print("Client connected") async def on_disconnect(ws): print("Client disconnected") ``` -------------------------------- ### Causal Linking Trace Example Source: https://github.com/banditburai/starhtml/blob/main/docs/designs/2026-02-17-debugger-timeline-tab.md Illustrates the hierarchical structure of events within a trace, showing parent-child relationships and depth. ```text traceId=7: [user-action] click #increment-btn parentId=null depth=0 [sse-lifecycle] started /increment parentId=0 depth=1 [signal-change] count: 3 -> 4 parentId=0 depth=1 [effect-eval] effect#0 (text) 0.1ms parentId=2 depth=2 [dom-mutation] #counter text "3"->"4" parentId=3 depth=3 [sse-lifecycle] finished (45ms) parentId=0 depth=1 ``` -------------------------------- ### Send GET Request with @get() Action Source: https://github.com/banditburai/starhtml/blob/main/DATASTAR_REFERENCE.md The `@get()` action sends a GET request to a specified URL. The backend can respond with HTML elements that will be morphed into the existing DOM, updating the UI. ```html ``` -------------------------------- ### JavaScript Alert from Backend Source: https://github.com/banditburai/starhtml/blob/main/DATASTAR_REFERENCE.md Execute JavaScript code on the frontend that is sent from the backend. This example shows a simple alert message being displayed. ```javascript alert('This mission is too important for me to allow you to jeopardize it.') ``` -------------------------------- ### Toggle All Nested Menus Source: https://github.com/banditburai/starhtml/blob/main/DATASTAR_REFERENCE.md This example demonstrates toggling the open/closed state of multiple nested menus using a single button. The `toggleAll()` action with an `include` filter targets specific nested signals. ```html` block. Includes a copy button for easy data extraction.
```typescript
Implement `buildFullTraceHtml(traceId): string` — flat timestamped event dump in `` block with copy button.
```
--------------------------------
### Run Tests with Coverage
Source: https://github.com/banditburai/starhtml/blob/main/tests/unit/README.md
Execute all unit tests and generate an HTML coverage report for the starhtml module. This helps identify areas with missing test coverage.
```bash
uv run pytest tests/unit/ --cov=starhtml --cov-report=html
```
--------------------------------
### Run Specific Pytest Class
Source: https://github.com/banditburai/starhtml/blob/main/tests/README.md
Execute tests belonging to a specific class within a test file, for example, 'TestEventHandling' in 'test_handlers.py', using 'uv run pytest' with the class name appended after '::' and the '-v' flag.
```bash
uv run pytest tests/unit/test_handlers.py::TestEventHandling -v
```
--------------------------------
### Patch 2: Outside Modifier Race Fix (Same-event)
Source: https://github.com/banditburai/starhtml/blob/main/patches/README.md
Registers a capture-phase listener to snapshot an element's visibility state at the start of an event. This prevents the outside handler from incorrectly closing elements that were hidden when the event began.
```javascript
document.addEventListener(eventType, handler, true); // true for capture phase
// ... inside capture handler
const isHidden = element.style.display === "none";
if (isHidden) {
// suppress outside event
}
```
--------------------------------
### Run Specific Test File
Source: https://github.com/banditburai/starhtml/blob/main/tests/unit/README.md
Execute unit tests from a particular file, such as test_datastar_attrs.py. Use the -v flag for verbose output.
```bash
uv run pytest tests/unit/test_datastar_attrs.py -v
```
--------------------------------
### Filter Elements by Attribute Name Prefix
Source: https://github.com/banditburai/starhtml/blob/main/tests/browser/test_attribute_selector.html
This approach manually queries all elements and then filters them using JavaScript to find elements whose attribute names start with a specific prefix. This is useful when standard CSS selectors are insufficient or for more complex attribute matching.
```javascript
const allElements = document.querySelectorAll('*');
const resizeElements = Array.from(allElements).filter(el => Array.from(el.attributes).some(attr => attr.name.startsWith('data-on-resize')) );
console.log('Elements with data-on-resize* attributes:', resizeElements.length);
```
--------------------------------
### Client-Side HTTP Actions with StarHTML
Source: https://context7.com/banditburai/starhtml/llms.txt
Generate Datastar action expressions for making HTTP requests from the browser. Supports basic methods (GET, POST, PUT, DELETE) and advanced options like dynamic URLs, custom content types, conditional requests, and custom payloads.
```python
from starhtml import *
app, rt = star_app()
@rt("/")
def home():
return Div(
(item_id := Signal("item_id", 1)),
# Basic HTTP actions
Button("Fetch", data_on_click=get("/api/data")),
Button("Save", data_on_click=post("/api/save")),
Button("Update", data_on_click=put("/api/update")),
Button("Delete", data_on_click=delete("/api/delete")),
# Dynamic URL with Python variable
Button("Load Item", data_on_click=get(f"/api/items/{item_id._initial}")),
# With options
Button(
"Submit Form",
data_on_click=post("/api/submit", contentType="form"),
),
# Conditional request
Button(
"Save if Valid",
data_on_click=is_valid.then(post("/api/save")),
),
# Custom payload (not all signals)
Button(
"Save Text",
data_on_blur=post("/api/edit", payload={"text": js("evt.target.innerText.trim()")}),
),
)
```
--------------------------------
### SSE Best Practice: Preserving IDs on Element Replacement
Source: https://github.com/banditburai/starhtml/blob/main/API.md
When replacing elements using SSE, it's crucial to preserve the `id` of the target element. This ensures that subsequent selectors continue to work correctly for future updates. The example shows how to replace content while maintaining the element's ID.
```python
# yield elements(
# Div("New content", id="messages", cls="messages-container"),
# "#messages" # Replacement still has id="messages"
# )
```
--------------------------------
### Activate StarHTML Debugger with serve()
Source: https://github.com/banditburai/starhtml/blob/main/docs/designs/2026-02-15-starhtml-debugger.md
When `debug=True` is passed to `serve()`, the StarHTML Debugger is automatically registered and injected into the page. Set `debug=False` (default) for zero overhead.
```python
app.serve(debug=True)
```
--------------------------------
### Client-side WebSocket with Datastar
Source: https://context7.com/banditburai/starhtml/llms.txt
Establishes a WebSocket connection and handles incoming messages to update the DOM. Input is sent as JSON upon pressing Enter.
```python
from starhtml import *
from starhtml.core.signals import Signal
@rt("/")
def home():
return Div(
Script("""
const ws = new WebSocket(`ws://${location.host}/chat`);
ws.onmessage = (e) => document.getElementById('output').innerHTML = e.data;
"""),
Input(id="input", onkeyup="if(event.key==='Enter')ws.send(JSON.stringify({message:this.value}))"),
Div(id="output"),
)
```
--------------------------------
### Live Chat with Server-Sent Events
Source: https://github.com/banditburai/starhtml/blob/main/API.md
Implement a real-time chat application using Server-Sent Events (SSE). This snippet demonstrates how to handle user input, send messages to the server, and receive updates in real-time.
```python
from starhtml import *
import time
def chat_app():
message = Signal("message", "")
sending = Signal("sending", False)
return Div(
message, sending, # Signals render as hidden setup attributes
H1("Live Chat"),
# Messages container
Div(id="messages", cls="messages-container"),
# Chat input form
Form(
Input(
placeholder="Type your message...",
data_bind=message, # Two-way bind to message signal
data_attr_disabled=sending, # Disable while sending
cls="message-input"
),
Button(
data_text=sending.if_("Sending...", "Send"),
type="submit",
data_attr_disabled=sending | ~message, # Disabled when sending or empty
cls="send-button"
),
# post() sends all current signal values to the server
data_on_submit=(post("/chat/send"), {"prevent": True}),
cls="chat-form"
),
cls="chat-app"
)
```
--------------------------------
### Basic Datastar Signal Usage
Source: https://github.com/banditburai/starhtml/blob/main/DATASTAR_REFERENCE.md
Declare a signal with an initial value and display it using a data attribute. The '$foo' signal is initialized to '1' and its value is rendered.
```html
```
--------------------------------
### Create Element Reference (Key)
Source: https://github.com/banditburai/starhtml/blob/main/DATASTAR_REFERENCE.md
Use `data-ref:key` to create a signal that references the element. The signal name is derived from the key.
```html
```
--------------------------------
### Update Datastar Version
Source: https://github.com/banditburai/starhtml/blob/main/patches/README.md
Use this command to update the Datastar version. The 'v' prefix is optional. This downloads vanilla Datastar, verifies patches, and updates the version tracking file.
```bash
python scripts/update_datastar.py 1.0.0-RC.8
bun run build
```
--------------------------------
### Initialize StarHTML with Debug Parameter
Source: https://github.com/banditburai/starhtml/blob/main/docs/plans/2026-02-15-starhtml-debugger.md
Configure the debug parameter in StarHTML's initialization, with support for overriding via the STARHTML_DEBUG environment variable. A warning is printed to stderr when debug mode is enabled.
```python
self.debug = debug
env_debug = os.environ.get("STARHTML_DEBUG")
if env_debug is not None:
self.debug = env_debug in ("1", "true", "yes")
if self.debug:
print("WARNING: StarHTML debug mode is ON. Do not use in production.", file=sys.stderr)
```
--------------------------------
### Performance Comparison of Selection Methods
Source: https://github.com/banditburai/starhtml/blob/main/tests/browser/test_attribute_selector.html
Compares the performance of selecting all elements ('*') versus selecting common HTML tags using querySelectorAll within a loop. This helps in understanding the performance implications of broad versus targeted selections.
```javascript
console.time('querySelectorAll(\* )');
for (let i = 0; i < 100; i++) {
document.querySelectorAll('*');
}
console.timeEnd('querySelectorAll(\* )');
console.time('querySelectorAll(common tags)');
for (let i = 0; i < 100; i++) {
document.querySelectorAll(commonTags);
}
console.timeEnd('querySelectorAll(common tags)');
```
--------------------------------
### Implement Debug Parameter in StarHTML.__init__
Source: https://github.com/banditburai/starhtml/blob/main/docs/plans/2026-02-15-starhtml-debugger.md
This code snippet shows the necessary modification to the StarHTML class constructor to accept and process the 'debug' parameter.
```python
import os, sys
# In src/starhtml/core.py, add 'debug' parameter to StarHTML.__init__()
```
--------------------------------
### Icon Sizing Options
Source: https://github.com/banditburai/starhtml/blob/main/API.md
Illustrates various ways to control the size of icons, including explicit pixel/rem values, separate width/height, and Tailwind CSS size classes. Defaults to 1em if no size is specified.
```python
# Explicit size (applied to both width and height)
Icon("lucide:home", size=24) # 24px
Icon("lucide:home", size="1.5rem") # 1.5rem
# Separate width/height
Icon("lucide:home", width=32, height=24)
# Tailwind size classes (extracted automatically)
Icon("lucide:home", cls="size-6") # 1.5rem from Tailwind mapping
Icon("lucide:home", cls="w-8 h-8") # 2rem
Icon("lucide:home", cls="size-[2rem]") # Arbitrary value
# No size specified → defaults to 1em (inherits from font size)
Icon("lucide:home")
```
--------------------------------
### star_app - Application Factory
Source: https://context7.com/banditburai/starhtml/llms.txt
Creates a StarHTML application instance. It supports various configurations including database integration, session management, middleware, and development tools like live reload.
```APIDOC
## star_app - Application Factory
Creates a StarHTML application instance with routing, sessions, middleware, and optional database integration. Returns a tuple of the app and a route decorator.
### Parameters
- **db_file** (str) - Optional - Path to the SQLite database file.
- **items** (dict) - Optional - Defines database table schema for ORM.
- **title** (str) - Optional - Title for the application.
- **debug** (bool) - Optional - Enables debug mode.
- **devtools** (bool) - Optional - Enables developer tools.
- **live** (bool) - Optional - Enables live reload.
- **hdrs** (list) - Optional - List of HTML headers to include.
- **secret_key** (str) - Optional - Secret key for session encryption.
- **session_cookie** (str) - Optional - Name of the session cookie.
- **max_age** (int) - Optional - Maximum age of the session cookie in seconds.
- **middleware** (list) - Optional - List of middleware functions to apply.
- **on_startup** (list) - Optional - List of functions to run on application startup.
- **on_shutdown** (list) - Optional - List of functions to run on application shutdown.
- **inline_icons** (bool) - Optional - Enables inline SVG icon rendering.
### Request Example
```python
from starhtml import *
# Basic app creation
app, rt = star_app()
# With database integration (SQLite via fastlite)
app, rt, items, Item = star_app(
db_file="data.db",
items=dict(id=int, title=str, done=bool),
title="Todo App",
debug=True,
devtools=True,
live=True, # Enable live reload
hdrs=[Script(src="https://cdn.tailwindcss.com")],
)
# With custom session and middleware
app, rt = star_app(
secret_key="my-secret-key",
session_cookie="my_session",
max_age=7 * 24 * 3600, # 7 days
middleware=[compression()], # Built-in gzip/brotli
on_startup=[init_database],
on_shutdown=[close_database],
inline_icons=True, # Server-side SVG rendering
)
```
```
--------------------------------
### Backend Actions
Source: https://github.com/banditburai/starhtml/blob/main/DATASTAR_REFERENCE.md
Directives for making HTTP requests to the backend.
```APIDOC
## @get()
### Description
Sends a `GET` request using the Fetch API. The response should contain Datastar SSE events.
### Method
GET
### Endpoint
`/endpoint`
### Parameters
#### Path Parameters
N/A
#### Query Parameters
N/A
#### Request Body
N/A
### Request Example
```html
```
### Response
N/A (Handles SSE, HTML, JSON, JavaScript)
## Options
### Description
Options available for backend actions.
### Parameters
#### Path Parameters
N/A
#### Query Parameters
N/A
#### Request Body
N/A
### Options List
- **contentType**: `'json'` or `'form'`. Defaults to `'json'`.
- **filterSignals**: An object `{include: RegExp, exclude: RegExp}` to filter signals sent with the request.
- **selector**: A CSS selector for a form when `contentType` is `'form'`.
- **headers**: An object of custom headers.
- **openWhenHidden**: `true` or `false`. Defaults to `false`.
- **retryInterval**, **retryScaler**, **retryMaxWaitMs**, **retryMaxCount**: Control retry behavior.
- **requestCancellation**: `'auto'`, `'disabled'`, or an `AbortController`. Defaults to `'auto'`.
### Request Example
```html
```
### Response
N/A
## Response Handling
### Description
Backend actions handle different response `content-type` values.
### Response Types
- `text/event-stream`: Standard SSE with Datastar events.
- `text/html`: HTML to patch into the DOM. Can use `datastar-selector`, `datastar-mode`, and `datastar-use-view-transition` headers.
- `application/json`: JSON signals to patch. Can use `datastar-only-if-missing` header.
- `text/javascript`: JavaScript to execute. Can use `datastar-script-attributes` header.
```
--------------------------------
### Python Comparison and Math Operators to JavaScript
Source: https://github.com/banditburai/starhtml/blob/main/API.md
Demonstrates the direct translation of common Python comparison (`>=`, `==`) and math (`*`, `/`) operators into their JavaScript counterparts for use in reactive expressions.
```python
age >= 18 # → $age >= 18
count == 0 # → $count === 0
price * quantity # → $price * $quantity
(current / total) * 100 # → ($current / $total) * 100
```
--------------------------------
### StarHTML Debugger Demo Page
Source: https://github.com/banditburai/starhtml/blob/main/docs/plans/2026-02-15-starhtml-debugger.md
A demo page for the StarHTML debugger, demonstrating its features including SSE events and dynamic content updates. It requires `star_app`, `sse`, and `signals` from `starhtml`.
```python
from starhtml.starapp import star_app
from starhtml.datastar import *
app, rt = star_app(debug=True)
count = Signal("count", 0)
@rt("/")
def home():
return Div(
H1("Debugger Demo"),
P("Open the debug panel with Ctrl/Cmd+Shift+. or click the tab at the bottom."),
Div(
Button("Increment", data_on_click=sse("/increment")),
Button("Add Element", data_on_click=sse("/add-element")),
Span(data_text=count, id="counter"),
),
Div(id="dynamic-content"),
)
@rt("/increment")
async def increment(request):
from starhtml.realtime import sse, signals
@sse(request)
async def stream():
yield signals(count=count + 1)
return stream
@rt("/add-element")
async def add_element(request):
from starhtml.realtime import sse, elements
@sse(request)
async def stream():
yield elements(
P("New paragraph added!", cls="text-green-500"),
selector="#dynamic-content",
mode="append",
)
return stream
from starhtml.server import serve
serve(port=5030)
```
--------------------------------
### SSE Event Handling for Quiz Application
Source: https://github.com/banditburai/starhtml/blob/main/DATASTAR_REFERENCE.md
This snippet shows how to handle Server-Sent Events (SSE) for a quiz. It fetches a question, allows user input, and displays feedback based on whether the answer is correct. State is driven from the backend.
```html
You answered “”.
That is correct ✅
The correct answer is “” 🤷
```