Rat
A tiny web framework where one .rat file is a server, a page, and its styles.
> server
count: 0
> page
<h1> hello, rat
<p> clicked [count] times
<button on_click[count << count + 1]> bump hello, rat
clicked 0 times
Zero to dev server
No toolchain, no node_modules. The installer drops one binary on your PATH; rat new scaffolds a project; rat start serves it with hot reload. Prefer a direct download? Everything's on the downloads page.
One binary, the whole pipeline
Server, parser, renderer, data, realtime — every box below ships inside the single rat executable. Watch a request make the trip.
CSS, reimagined
Styles are part of the dialect, not a language bolted on. Indentation instead of braces, design tokens as a state block, bracket references instead of var(...) spelling, token math that compiles to calc(). It all ships as plain custom properties — view source on this page and you'll find exactly this pattern, hot-reloading like everything else.
> []
ink: rgb(95 58 58)
accent: crimson
gap: 1rem
> [.card]
color: [ink]
padding: [gap] [gap * 2]
border-left: 3px solid [accent]
> [.card:hover]
border-color: [ink]
> [@media (max-width: 600px)]
[.card]
padding: [gap * 0.5] Python, one call away
Drop a .py file in lang/python/ and every function in it is callable from server state, handlers, and APIs. Rat keeps a warm worker pool and bridges arguments and results as JSON — no microservice, no FFI, no glue code.
lang/python/text.py
def analyze(text):
words = text.split()
stats = {'words': len(words)}
stats['longest'] = max(words, key=len)
return stats pages/report/page.rat
> server
report: text.analyze('the quick brown fox')
> page
<p> [report.words] words, longest [report.longest] Also in the box
Components — any file in pups/ becomes a tag, attrs become props.
SQLite built in — models, queries, and migrations with zero setup.
Realtime channels — broadcast to subscribed pages over SSE.
Function APIs — a function in api/ is a JSON endpoint.
Static builds — rat build emits plain HTML for dumb hosting.
One binary deploys — copy the executable and your project folder. Done.
It's fast
Median of five runs across three project sizes. The number to look at is hot reload at 1000 pages — the loader reparses only the touched file, so even a thousand-page project bounces in 39 ms.
| project size | cold load | warm load | hot reload | full build |
|---|---|---|---|---|
| 10 pages | 1.5 ms | 0.5 ms | 0.5 ms | 5 ms |
| 100 pages | 9.8 ms | 3.6 ms | 3.1 ms | 54 ms |
| 1000 pages | 170.9 ms | 48.5 ms | 39 ms | 840 ms |
The docs walk through the dialect a piece at a time, with a runnable snippet for every feature. Start with the index or jump straight to setup.