A Python framework for hypermedia-driven applications. Write templates in .hyper syntax that compile to type-safe, streaming Python.
Write a template:
# Button.hyper
label: str
variant: str = "primary"
disabled: bool = False
---
<button class="btn btn-{variant}" {disabled}>
{label}
</button>
Use it:
from Button import Button
html = str(Button(label="Save", variant="danger"))
# <button class="btn btn-danger">Save</button>- Type-safe props — Catch errors before runtime with Python type annotations
- Streaming by default — Components are generators, ready for HTTP streaming
- Full Python — Any expression, import, or control flow inside templates
- IDE intelligence — Autocomplete, go-to-definition, and type checking in JetBrains
- Rust-powered compiler — Fast compilation with helpful error messages
- Content collections — Load and validate Markdown, JSON, YAML, TOML with typed models
# Card.hyper
title: str
---
<div class="card">
<h2>{title}</h2>
<div class="card-body">
{...}
</div>
</div>
# Page.hyper
from components import Card, Badge
items: list[dict]
---
for item in items:
<{Card} title={item['name']}>
<{Badge} text="New" />
<p>{item['description']}</p>
</{Card}>
end
All Python control flow works inside templates — if/elif/else, for, while, match/case, try/except, with, and async variants. Blocks end with end instead of relying on indentation.
status: str
---
match status:
case "loading":
<div class="spinner" />
case "error":
<p class="error">Something went wrong</p>
case _:
<p>Ready</p>
end
Components are generators that yield chunks, ready for HTTP streaming out of the box:
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from pages import Feed
app = FastAPI()
@app.get("/feed")
def feed():
return StreamingResponse(Feed(posts=posts), media_type="text/html")Or render to a string:
html = str(Feed(posts=posts))is_active: bool
data: dict = {"user-id": 123}
---
# Boolean — renders as <button disabled> or <button>
<button {disabled}>Click</button>
# Class — lists, dicts, conditional
<div class={["btn", {"active": is_active}]}>...</div>
# Style — dict to inline CSS
<p style={{"color": "red"}}>Alert</p>
# Data/ARIA — auto-prefixed
<div {data} aria={{"label": "Close"}}>...</div>
# Spread
<a {**attrs}>Link</a>
Load and validate structured content from JSON, YAML, TOML, or Markdown files:
from hyper.content import MarkdownCollection
class Post(MarkdownCollection):
title: str
date: str
class Meta:
pattern = "posts/*.md"
posts = Post.load() # Typed, validated, with auto-generated html/toc/slug fieldsWorks with dataclasses, Pydantic, and msgspec.
- JetBrains (PyCharm, IntelliJ) — Full Python intelligence inside
.hyperfiles: autocomplete, go-to-definition, type checking, auto-transpilation on save - TextMate — Syntax highlighting bundle
See CONTRIBUTING.md.