Write html/template and Go handlers, and the page updates itself. The goal is app-like screens without an SPA, a JSON API or a build step, so there's no JavaScript here that you have to write.
Write html/template and Go handlers. The server re-renders on each action and patches only what changed. Every demo below is a real app running on this page, and none of it is JavaScript you had to write.
Type a name. Your headline updates and your line joins the wall, along with everyone else's — including anyone else reading this page right now. Open this page in a second tab and watch it land there too, with no reload. The code for all of it is directly below.
+Type a name. Your headline updates and your line joins the wall underneath it, next to whoever else is here right now. Open this page in a second tab and watch the same line land there, with no reload. The whole program is directly below.
Every section below points at lines you have just read — except the pending state, which the wall has no slow work to demonstrate, and which says so. Each one also runs here as its own app, so you can try it.
+Each section below picks out a line you have just read and runs it here as its own app, so you can try it on its own. The exception is the pending state: the wall answers instantly, so it has no slow work to show, and that section borrows two other apps instead.
This is the one thing the app above cannot show you: the wall answers instantly, so it has no pending state to render. Both apps below do have slow work. The first is the way to reach for — the pending flag is a template variable, so the spinner is ordinary Go and ordinary HTML, with no new attribute to learn.
+These are the two borrowed apps, and both of them do slow work. Reach for the first one: the pending flag is a template variable, so the spinner is ordinary Go and ordinary HTML, with no new attribute to learn.
Here a plain <button name="greet"> is already the action. lvt-* attributes are an escape hatch for what HTML cannot express, not the main interface.
Server-rendered HTML over a socket, like LiveView. Ordinary form markup and no state in the browser, like htmx. Both of them are years more mature than this, and each row below says where the other one still wins.
html/template and keep live behavior in one app model instead of stacking layers.html/template cannot, and that is a real thing to give up. The trade is a code generation step and one more library to track.lvt-el: attribute toggles a class or an attribute on a DOM event and stops there. That covers a dropdown. It does not cover a widget with its own model.It targets what Go teams actually ship: admin screens, internal tools, CRUD, dashboards, approvals, uploads, auth, and the occasional shared view.
+Admin panels, internal tools, CRUD, dashboards, approvals, uploads, auth, and the occasional shared view. That is what this is for.
The UI patterns catalog has focused examples: loading states, inline validation, SPA-style navigation, sortable tables, pubsub, presence, server push. This site runs on LiveTemplate itself. See how it works.
+The UI patterns catalog has focused examples: loading states, inline validation, SPA-style navigation, sortable tables, pubsub, presence, server push. A LiveTemplate app renders every page on this site, including this one. See how it works.
$ go get github.com/livetemplate/livetemplate