xtemplate is a Go server that turns a directory of HTML templates into a hypermedia web application, treating templates themselves as route handlers with no separate application layer.
What is xtemplate?
xtemplate is a Go-based web server that uses HTML template files as the entire application layer. It accepts a directory of templates, parses them at startup, and serves HTTP requests according to file-based routing: for example, contacts.html handles GET /contacts and contacts/{id}.html handles GET /contacts/{id}. It runs on Go and can be deployed through its CLI, Docker images, a Caddy module, or embedded directly into any Go program as an http.Handler. The project is open source under the Apache 2.0 license and developed on GitHub.
Key Features
- File-based routing — Files map directly to URL paths:
admin/settings.htmlservesGET /admin/settings, andindex.htmlserves the directory root. - Any HTTP method and pattern — Template definitions such as
define "DELETE /contact/{id}"become routes with path parameters, enabling CRUD and custom methods. - Live reload — Templates are parsed once at startup and swapped on change, so development servers reflect edits without restart.
- Request-scoped dot context — Each request exposes
.Req,.Resp,.DB, and.FSso templates can access form values, path parameters, and database queries directly. - Safe by default — Uses Go’s
html/templateescaping for output, with optional sanitize and trust helpers for controlled raw HTML. - Static file optimization — Static assets get content hashes, SRI integrity attributes, precompressed encodings, and long-lived cache headers.
- Server-Sent Events —
define "SSE /path"blocks stream live updates to clients. - Multiple deployment modes — Run as a standalone CLI, a Docker container, a Caddy plugin, or a Go library.
Who is it for?
- Go developers who want to build server-rendered web apps without maintaining a separate JavaScript frontend or a route table.
- Hypermedia enthusiasts who want a template-centric approach to forms, navigation, and progressive enhancement with libraries like htmx.
- Small-team tool builders who need an embeddable web server inside a larger Go application, using templates as the UI layer.
What can you do with xtemplate?
- Build CRUD applications — The contacts example shows creating a list page, an edit form, and a POST handler all defined in
.htmlfiles with SQL queries against a configured provider. - Prototype with live reload — The CLI watches templates and swaps updated instances, so you can iterate on pages without restarting the server.
- Serve optimized static assets — xtemplate hashes files and emits SRI tags, so browsers cache safely and integrity is verified.
- Stream real-time updates — SSE route definitions let you push reload messages or data changes to connected clients with a few lines of template code.
How does xtemplate work?
- Create a directory of
.htmltemplates; each file ordefineblock maps to a URL route. - Run the CLI or Docker container pointed at that directory — xtemplate parses everything at startup.
- Requests are served by matching the request method and path to the template layout; on file changes, the live reloader swaps the instance.
Pricing
xtemplate is free and open source, released under the Apache 2.0 license.
FAQ
Is xtemplate free to use?
Yes. xtemplate is open source under the Apache 2.0 license, so you can use, modify, and distribute it freely, including in commercial projects.
Does xtemplate require a database?
No. A SQL provider can be configured as .DB in the dot context, but it's optional. Templates can also work with the request context and static files alone.
Can I use xtemplate with htmx?
Yes. The public example app infogulch/todoxt is a todos application built with xtemplate and htmx, and the template syntax supports returning HTML fragments for AJAX updates.
How does xtemplate handle routing?
Routing is file-based: admin/settings.html serves GET /admin/settings, and template definitions like define "DELETE /contact/{id}" handle other methods and path parameters. No separate route configuration is needed.







