Type-safe templates for Python, powered by Rust.
uvx hyper .
.hyper files compile to Python components with slots, type-safe arguments, and full IDE support.
1. Write a template. Props go above the ---, template body below.
# app/components/Greeting.hyper
name: str
---
<h1>Hello, {name}!</h1>
2. Compile it.
uvx hyper .
# ✓ app/components/Greeting.py
3. Use it.
from app.components import Greeting
@app.get("/", response_class=HTMLResponse)
def index():
return Greeting(name="World")Components compose like HTML elements. Children go in the default slot with {...}.
# app/components/ProductCard.hyper
name: str
price: float
image: str
on_sale: bool = False
---
<div class={["card", {"sale": on_sale}]}>
<img src={image} alt={name} />
<h3>{name}</h3>
if on_sale:
<span class="badge">Sale</span>
end
<p class="price">${price:.2f}</p>
</div>
# app/pages/Store.hyper
from app.layouts import Layout
from app.components import ProductCard
products: list[Product]
---
<{Layout} title="Store">
for product in products:
<{ProductCard}
name={product.name}
price={product.price}
image={product.image}
on_sale={product.on_sale}
/>
end
</{Layout}>
The template body is the function body. Any valid Python works. Blocks end with end.
from app.enums import Status
from app.models import Product
status: Status
products: list[Product]
---
match status:
case Status.LOADING:
<div class="spinner" />
case Status.ERROR:
<p class="error">Something went wrong</p>
case Status.OK:
if not products:
<p>No products found</p>
else:
<ul>
for product in products:
<li>{product.name}</li>
end
</ul>
end
end
Every component is a generator, so streaming works out of the box:
from fastapi.responses import StreamingResponse
from app.pages import Store
@app.get("/store")
def store():
return StreamingResponse(Store(products=products), media_type="text/html")- JetBrains (PyCharm, IntelliJ) — Full Python intelligence inside
.hyperfiles: autocomplete, go-to-definition, type checking, auto-transpilation on save - TextMate / VS Code — Syntax highlighting
Hyper's component and attribute syntax was inspired by tdom.
See CONTRIBUTING.md.