Build your first app¶
About 10 minutes after Python 3.10–3.14 and either
uv or an activated virtual
environment. Node.js is not required.
If terms such as project folder, terminal, virtual environment, or development server are new,
use Your first application with VS Code. In Posit Workbench, use the
hedron-posit beginner walkthrough.
Install from PyPI: hedron>=1.0.0 is the compatibility floor. For a new application,
prefer the current bounded range hedron>=1.1.2,<1.2; use hedron==1.1.2 when you
need an exact reproducible environment. For a higher-level application API, start with
Edron. Other pins and extras: Installation.
You will learn¶
- how
hedron newcreates an ordinary Python application; - how a returned component tree becomes a complete HTML page;
- how
@app.viewreturns a targeted HTML fragment handle; - how to make one edit, run a diagnostic check, and choose the next tutorial step.
You do not need prior HTMX or JavaScript knowledge. The core concepts page explains the model after you have seen it work.
1. Scaffold and run¶
Create and activate a new empty virtual environment first (python3 -m venv .venv
then source .venv/bin/activate, or on Windows py -3 -m venv .venv and
.\.venv\Scripts\Activate.ps1). If PowerShell blocks scripts, use
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned once, or activate.bat.
The second pip install installs the generated project and its declared Hedron pin.
The uv path performs the equivalent step through uv sync.
Open http://127.0.0.1:8000. You should see Hello from hedron new.
Click Refresh status. The timestamp should change without a full-page reload. That
confirms the browser requested /status, Hedron authorized the declared target, and
HTMX replaced only the status region.
What just happened?¶
| Browser action | Server behavior | Visible result |
|---|---|---|
Open / |
The page route returns a Page and Hedron renders a full document |
The Hello page loads |
| Click Refresh status | HTMX requests /status for the declared region |
Only the status timestamp changes |
| Send the wrong target | Hedron rejects a target outside the route’s region policy | The request fails closed with HTTP 403 |
That page/fragment distinction is the central Hedron interaction model. The next guide lets you inspect it directly; you do not need to understand HTMX before completing this quickstart.
2. Make one edit¶
The generated app.py looks like this (you can paste it if scaffold is unavailable):
import os
from datetime import datetime, timezone
from hedron import Hedron, Stack, Text, ToastHost, html
app = Hedron(
title="Hedron App",
security="standard",
explorer="off",
session_secret=os.environ.get("HEDRON_SESSION_SECRET", "replace-in-production"),
)
@app.view("/status")
def status():
stamp = datetime.now(timezone.utc).strftime("%H:%M:%S UTC")
return html.div(
Text(f"All systems operational · refreshed {stamp}"),
role="status",
aria={"live": "polite"},
)
@app.action("/ping", fallback="/")
def ping():
from hedron import refresh
return refresh(status).toast("Refreshed")
@app.page("/")
def home():
return Stack(
Text("Hello from hedron new"),
status(),
status.refresh_button("Refresh status"),
ping.button("Ping"),
ToastHost(),
)
The canonical 1.0 roles are @app.page, @app.view, and @app.action; see the
Hedron API.
Change:
to:
Save the file. Uvicorn reloads and the browser shows the new text.
Optional: typed action form with validation¶
For forms, keep validation in the typed action boundary with FormBody and explicit controls.
from typing import Annotated
from pydantic import BaseModel, Field
from hedron import FormBody
class QuickNote(BaseModel):
message: str = Field(min_length=1, max_length=200)
@app.action("/notes", fallback="/")
def add_note(data: Annotated[QuickNote, FormBody()]):
return Text(data.message)
# Inside the Stack returned by home():
# add_note.form(submit_label="Add note")
Add that final expression as another child of the existing Stack, restart if necessary,
and reload the page. Hedron renders the model-derived field, includes the CSRF boundary, and
returns validation errors through the form. For persistence and an explicit refresh target,
continue to Build a notes app.
Scaffolds: hedron new NAME --template crud (also shows DataWorkspace.with_screen).
3. Verify the project¶
Informational findings on a development scaffold are normal. Errors include a
remediation and a HED-* diagnostic code (see Error codes).
If something fails¶
| Symptom | Fix |
|---|---|
hedron: command not found |
Use python -m hedron, or use the uvx command above |
ModuleNotFoundError: hedron |
Run uv sync or python -m pip install -e . inside the generated directory |
| Resolver conflict | Start in a clean environment; see Compatibility |
| Port 8000 is busy | Add --port 8001 and open that port |
| Refresh does nothing | See HTMX troubleshooting |
For Python installation, Windows commands, optional extras, proxies, and adapters, use Installation.
What was generated?¶
hedron new writes an ordinary app.py, a pyproject.toml with a bounded Hedron pin,
and an empty components/ directory for project-owned components. The generated page
declares a canonical view and returns a small fragment for that view.
my-hedron-app/
├── app.py # application, page, action, and view handlers
├── pyproject.toml # dependencies and bounded Hedron pin
└── components/ # empty component root, ready for project components
These are normal Python project files. Hedron does not generate a separate JavaScript application or require Node.js for the production build.
Continue¶
| If you want to… | Continue with |
|---|---|
| Understand the refresh you just used | What is HTMX? |
| Add another independently updating region | HTMX interactions |
| Submit data safely | Minimal form POST |
| See the full beginner-to-production sequence | Learning path |
The recommended next project is Build a notes app, which carries this same application through a form, persistence, authentication, and deployment checks.