Skip to content

Getting Started

LoboGuardian 🐺 edited this page Jul 11, 2026 · 4 revisions

Getting Started

This page takes you from zero to a running reactive HTeaLeaf app in about five minutes.

1. Install

⚠️ This wiki documents the develop branch. The current PyPI release (0.3.4) ships an older API, so install from the development branch for now:

python -m venv .venv && source .venv/bin/activate
pip install "git+https://github.com/Az107/HTeaLeaf@develop" uvicorn

2. Write a minimal app

Create myapp.py:

from htealeaf import HteaLeaf, adapters, use_state
from htealeaf.js import js
from htealeaf.elements import html, head, body, div, button, h1

app = HteaLeaf(adapters.ASGI)

@app.route("/")
async def index():
    count = use_state(0)

    @js
    def increment():
        count.set(count.get() + 1)

    return html(
        head(),
        body(
            h1("Count: ", count),
            button("Click me").attr(onclick=increment()),
        ),
    )

Three things to notice:

  • use_state(0) declares client-side state (LocalState) — it lives in the page, no server round-trip.
  • The @js function is transpiled to JavaScript (JSCode and JS from Python) and injected into <head> automatically.
  • Handlers can be sync or async def — async ones are awaited natively, sync ones run in a thread executor. Script injection works the same in both.

3. Run it

uvicorn myapp:app

Open http://127.0.0.1:8000 — clicking the button increments the counter, entirely client-side.

The server responds with plain HTML plus two injected <script> blocks (the state initializer and your transpiled function):

<head>
  <script>const localstate_85086a80dd45 = new LocalState(0, "localstate_85086a80dd45");</script>
  <script>function increment() {
      localstate_85086a80dd45.set(localstate_85086a80dd45.get() + 1);
  }</script>
</head>
<body>
  <h1>Count: {{localstate_85086a80dd45}}</h1>
  <button onclick='increment()'>Click me</button>
</body>

The {{...}} placeholder is hydrated to 0 on load by helper.js, which HTeaLeaf serves at /_engine/helper.js and injects on every HTML response.

4. Where to go next


Next: Routing

Clone this wiki locally