# Frontage > Frontage is a fine-grained reactive UI framework for Python in the browser, running on its own > Python runtime compiled to WebAssembly, with an HTTP server (`frontage-server`, Rust around the > same runtime) in the same package. Apache 2.0, by Optersoft. Current version: 0.17.1. - Install: `pip install frontage` (Python 3.14; the wheel for macOS and Linux carries the compiler and the server binary). `uvx frontage …` runs the command line without installing. - An app is a directory of static files: `frontage build APP --out DIR` writes the page, the runtime and the app's import closure as precompiled bytecode. No JavaScript toolchain. - Signals, memos and effects update the exact text node or attribute that read them; a component body runs once. Templates are Python 3.14 template strings, `html(t"…")`, or the `h` builder (`h.div(…)`). - Commands: `frontage build`, `serve` (dev server that swaps changed modules into the page), `prerender`, `site`, `check`, `new server`, `islands`, `tailwind`; `frontage-server app.py`. ## Rules a model should know before writing Frontage code - The browser runs Frontage's own runtime, a subset of Python: no `typing` at runtime, no dataclasses, string annotations only, and only the standard modules the runtime has. PyPI packages with C extensions do not run in the page. - `html(f"…")` is plain text, not a template: use a t-string, `html(t"…")`. `frontage check` flags it. - Anything callable inside a template is a hole that updates in place. Name the function you put in a hole; a `lambda` inside `{…}` is flagged by `frontage check`. - APIs where order matters take pairs, not dicts: `record(("title", text()), ("n", integer()))`, `tabs([("Trend", view), …])`. - A page's module must not import `frontage_server`: put the shared `record` in its own module, or `frontage build` ships the server into the browser and the page fails at boot. - On the server, module-level state is per worker (one interpreter per worker thread); keep shared state in the database. `@app.on_startup(once=True)` runs a hook on one worker. - Build the page from a folder that holds only the page when `App(static=…)` serves the output. - `frontage-server --runtime cpython app.py` runs the same file with the handlers on CPython, for code that needs pandas or other CPython packages. ## Docs ### Building and shipping - [Basic](https://academy.optersoft.com/python/frontage/basic): A first app in the browser, the signal that makes it react, and the rule that decides whether a piece of the page updates itself. - [Ship](https://academy.optersoft.com/python/frontage/ship): From a folder of Python to a public URL: three mistakes a browser catches and CPython misses, what a build writes, a pipeline that blocks a broken page. - [Template](https://academy.optersoft.com/python/frontage/template): Everything a template can say: holes, attributes, properties, class and style prefixes, delegated events, two-way bindings, and the `h` builder. - [Style](https://academy.optersoft.com/python/frontage/style): Tailwind CSS with no build step while learning and a one-command build for production. - [Flow](https://academy.optersoft.com/python/frontage/flow): Show, Switch and a keyed For that keep their elements instead of rebuilding them, and a Store that updates one hole per field. ### Data and navigation - [Async](https://academy.optersoft.com/python/frontage/async): Resource, loading and error boundaries, Action, async memos and transitions. - [Router](https://academy.optersoft.com/python/frontage/router): The URL as state: nested routes, preloading links, a query cache, titles, lazy routes, what a screen reader hears. - [State](https://academy.optersoft.com/python/frontage/state): A class whose attributes are signals, widgets bound to them, timers, and merging fresh data into a list. - [Form](https://academy.optersoft.com/python/frontage/form): One `frontage.schema` record checking a form as it is typed and the server's answer before anything reads it. ### Showing data - [Chart](https://academy.optersoft.com/python/frontage/chart): Declarative charts (Vega-Lite's grammar) drawn as SVG or on a canvas, from a table. ### Making sure it works - [Testing](https://academy.optersoft.com/python/frontage/testing): Run an app with no browser, click its widgets and assert on what it drew, from pytest. ### Faster first paint - [Prerender](https://academy.optersoft.com/python/frontage/prerender): Pages written as finished HTML at build time and hydrated in the browser. - [Islands](https://academy.optersoft.com/python/frontage/islands): A static page that downloads no runtime, with interactive parts that boot when their trigger fires. - [Content](https://academy.optersoft.com/python/frontage/content): A directory of Markdown whose front matter a schema checks, rendered at build time. - [Sites](https://academy.optersoft.com/python/frontage/sites): `frontage site`: the directory is the site map, layouts are components, endpoints are modules, locales are directories. ### A server of your own (frontage-server) - [Server](https://academy.optersoft.com/python/frontage/api): Routes whose signature is the routing, one record validating the form and the body it posts, a database, SSE, OpenAPI. - [Routes and pages](https://academy.optersoft.com/python/frontage/routes): Router, redirect, file(), static files, uploads, error pages, and pages rendered per request with islands. - [Who is asking](https://academy.optersoft.com/python/frontage/auth): Sessions, Policy(auth=) with ApiKey, JWT, Basic and SessionAuth checked in Rust, CSRF, rate limits, body limits, timeouts, caching. - [Live](https://academy.optersoft.com/python/frontage/live): `@app.websocket`, a Hub that reaches every worker, and `frontage.live`, a WebSocket as a signal in the page. - [Running it](https://academy.optersoft.com/python/frontage/operate): `frontage new server`, testing.Server, settings, the drain, `--watch`, logs, metrics, the HTTP client, `--runtime cpython`. - [Polars](https://academy.optersoft.com/python/frontage/polars): A big dataset kept on a server with polars and asked named questions from the page. - [Database](https://academy.optersoft.com/python/frontage/database): A page that talks to Postgres with no server of its own, the authorisation in the database. ### Going further - [Components](https://academy.optersoft.com/python/frontage/components): Table, layout, map and signal processing that cost nothing until imported, and writing a component. - [Chat](https://academy.optersoft.com/python/frontage/chat): A conversation whose answer streams into one text node. - [Wasm libraries](https://academy.optersoft.com/python/frontage/wasm): Calling a C or Rust library from an app by importing it, and what a crossing costs. ## Site - [Frontage](https://frontage.optersoft.com/): the landing page - [Gallery](https://frontage.optersoft.com/gallery/): apps built with the real command, each measured cold - [Playground](https://frontage.optersoft.com/playground/): write an app and run it in the browser - [PyPI](https://pypi.org/project/frontage/): the package and its release history ## Optional - [Academy index](https://academy.optersoft.com/python/frontage): the course's landing page, with the order of the chapters