Routes and handlers like Spring Boot, pages built out of components like Vaadin — and the whole of both is .keal files. The C underneath opens sockets and moves bytes. It does not decide anything.
site.livePage("/", { req ->
var count = 0
view({ -> column([
h1("Clicked ${count} times"),
button("Click me", { e -> count = count + 1 })
]) })
}){"p":[["t","0.0.0","Clicked 1 times"]]}One patch. The browser sets one text node — no JSON schema, no endpoint, no client state, nothing to keep in sync.
| lines | what it is | |
|---|---|---|
| Keal | 6 604 | the whole framework: HTTP, routing, the component tree, the renderer, stylesheets, JSON, WebSocket framing, gzip, the scheduler, the session hub, the diff, the SQLite layer and the hashing security rests on |
| C | 786 | sockets, poll, byte blobs, files in pieces — two headers, no .c file |
| JavaScript | 143 | the browser client: open a socket, report an event, apply a patch |
import "kealeb/kealeb.keal"
val site = app("Hello")
site.page("/", { req -> column([
h1("Hello"),
p("from Keal")
])})
site.run(8080)Five lines and one import. It is a page, styled, in dark mode if the machine is, and it works in anything that can read HTML — there is no JavaScript on it at all.
Every socket is non-blocking, one poll drives everything, and a handler runs with nothing else running. Session state is an ordinary Keal object and a data race is not a thing that can be written here. The cost is stated rather than hidden: a handler that blocks blocks the server.
A live page keeps its tree on the server. An event runs a handler, the tree is built again, the two are compared, and what crosses the socket is the list of changes — seven kinds of patch, each one call in a browser.
No dependencies. SQLite arrives with a second import and one flag; a program that never opens a database never links against one. The hashing, the compression and the WebSocket framing are Keal.
SHA-256, HMAC and PBKDF2 against the vectors their specifications published. The gzip output handed to the system gzip and to Python, both required to give the bytes back. The browser client run against a real server on every build.