Web¶
A Web host is the browser counterpart to
Terminal. It runs an offscreen runtime, serves a small HTTP
shell, and streams cell frames to the client. Browser key, mouse, and resize
input re-enter the same @on_* path a terminal session uses.
There is no separate HTML paint backend. Grids, fields, components, and hooks are the same objects on both hosts.
Running a web app¶
Web().run(...) binds a stdlib HTTP server and keeps serving until interrupted.
This needs a normal Python process — not Pyodide.
from xnano import BaseGrid, Field, Web
class App(BaseGrid):
body: str = Field(default="hello, web!")
Web().run(App(), port=8000) # (1)!
- Optional:
host=,Web(state=..., width=..., height=..., title=...).
The default host uses Python's stdlib HTTP server via
serve_native.
One grid, two hosts¶
from xnano import BaseGrid, Field, Terminal, Web
class App(BaseGrid):
body: str = Field(default="hello!")
Terminal().run(App()) # terminal session
Web().run(App()) # browser session
Only one of these runs at a time in a given process. The grid class does not change.
Shared vs. per-visitor grids
Passing a BaseGrid instance reuses that object for every connection.
Passing the class (or a factory) builds a fresh root per visitor.
Request hooks¶
HTTP handlers are declared with decorators from xnano.requests
on grid methods. When that grid is served under Web (or a request server),
those routes are registered. They are not Terminal APIs — see
Requests.
What does not carry over¶
Some device and cursor controls only apply to a real terminal
(raw mode, alternate screen, moving the caret to a cell). On Web they are
no-ops. Grids, fields, components, and hooks still mean the same thing.
Next¶
- Requests —
@on_get_requestand related hooks - Grids / Events & Hooks — same as terminal