Webglue
A glue framework, not a monolith — Ring’s simplicity, Phoenix’s ambition. Webglue is a web framework written in Praxis, made of small, swappable libraries that share one contract: a request is a map, a response is a map, and a handler is a function from one to the other.
The idea
Clojure’s Ring is a specification rather than a library: a handler is a plain function, and middleware is a function that wraps a handler. Webglue takes that pattern and carries it through a whole framework — routing, HTTP servers, sessions, WebSockets, pub/sub, presence and server push — with the completeness of Phoenix or Laravel as the goal.
handler :: Request -> Response middleware :: Handler -> Handler
A Webglue application is a choice of libraries glued together. The framework is the convention, not the code.
Principles
- Small core, replaceable edges.
- Standards first: HTTP/1.1, HTTP/2, RFC 6455 WebSockets, IPv4 and IPv6.
- Design before code: each library starts as a specification.
- No hidden magic in the hot path. Composition is readable function calls — no macros, no
use. - The frontend is not a separate ecosystem: it will be Praxis too, compiled for the browser.
- Complete at release, monolithic never.
- Glue to the established standard-bearer instead of reinventing it — Bandit, Ecto, Absinthe, Oban, Swoosh, Redix.
Three more decisions are fixed: markup is data — a tree of plain Praxis vectors and maps, never strings; the wire format is DXN, with JSON as the fallback; configuration is CASC.
A first look
The demo application is one function. Read it from the bottom: the order of the wrapping is the order of the nesting, and this is the only place it is stated.
(defn app
"The application: one function, request to response."
[] :spec [-> function]
(-> (router/handler (routes))
(db/wrap {:repo webglue.demo.store.memory})
(wrap-user)
(static/wrap {:root (assets) :at "/assets"})
(session/wrap {:store (memory/store)})))Language and runtime
Webglue is written in Praxis and runs on the BEAM today: namespaces compile to .beam modules, long-lived state lives in OTP processes, and pub/sub runs on Erlang’s pg. Established BEAM libraries — Bandit, Plug, WebSock, Redix — are used through Praxis’ interop. The frontend half is planned for Praxis’ browser target.
Where it stands
Version 0.4.0 (29 September 2026) has seventeen libraries, all implemented and tested — about 480 tests — covering the contract, routing, two HTTP servers, sessions, static files, WebSockets, pub/sub, presence, clustering, Redis, server push, validation and a data-layer seam. Everything is marked experimental. The backend is the focus until 1.0; the frontend follows in 2.x.