gsx

module
v0.2.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 12, 2026 License: MIT

README

gsx

gsx is an ahead-of-time, JSX-like templating system for Go server-side HTML rendering.

It is built for teams that want:

  • HTML-first authoring
  • Go expressions and control flow
  • ahead-of-time compilation into .go
  • streaming renders to io.Writer
  • safe escaping by default
  • built-in layouts and slots
  • deterministic formatting and linting
  • a small runtime and predictable output

The compiler parses .gsx files, validates component calls and slot usage, and emits Go render functions that write directly to a writer.

Install

Library module:

go get github.com/jlcsoftgenie/gsx@latest

CLI:

go install github.com/jlcsoftgenie/gsx/cmd/gsx@latest

Status

This repository contains a complete, working implementation with:

  • compiler/parser/code generator
  • small runtime package
  • CLI: generate, build, check, lint, fmt, watch, init, version
  • formatter and linter
  • VS Code extension with syntax highlighting, snippets, hover, formatting, diagnostics, and language-server completions
  • layouts and named slots
  • examples
  • tests and integration coverage
  • benchmarks against html/template and gomponents

Current intentional constraints:

  • no runtime template parsing in the production path
  • no client runtime or hydration
  • no generic attribute spread, by design
  • imported GSX component packages must be discoverable during generate/check

Quick Look

package pages

component BaseLayout(title string) {
  <!doctype html>
  <html>
    <head>
      <title>{title}</title>
      <slot name="head" />
    </head>
    <body>
      <header><slot name="header" /></header>
      <main><slot /></main>
    </body>
  </html>
}

component HomePage(title string, users []User) {
  <BaseLayout title={title}>
    <div slot="header">
      <h1>{title}</h1>
    </div>

    if len(users) == 0 {
      <p>No users found.</p>
    } else {
      <ul>
        for _, user := range users {
          <li>{user.Name}</li>
        }
      </ul>
    }
  </BaseLayout>
}

Generated public API:

func RenderHomePage(w io.Writer, title string, users []User) error
func RenderHomePageWithSlots(w io.Writer, slots GSXHomePageSlots, title string, users []User) error

Why GSX Exists

html/template is safe and standard, but it stays string/template oriented and does its work at runtime. GSX takes a different tradeoff:

  • author templates in an HTML-shaped language
  • keep expressions and control flow in Go
  • resolve component contracts ahead of time
  • render with direct writes instead of interpreting a template AST per request

That makes it fit well for:

  • net/http apps
  • admin dashboards
  • HTMX responses
  • content-heavy pages
  • server-rendered internal tools

Syntax Summary

File structure:

  • package declaration is required
  • optional Go import declarations are supported
  • one or more component declarations per file

Supported template features:

  • HTML-like elements and self-closing tags
  • {expr} for Go expressions
  • local declarations with :=, var, and const
  • if / else if / else
  • for loops
  • comments: <!-- -->
  • doctype nodes
  • fragments: <fragment>...</fragment>
  • layouts and slots: <slot />, <slot name="head" />
  • trusted raw HTML: <raw html={runtime.HTML(...)} />
  • imported GSX components with standard Go imports and aliases, for example <shared.Panel />

See docs/syntax.md for the full language and grammar. See docs/cheatsheet.md for a compact authoring reference.

Slots And Layouts

Layouts are just components that render <slot> outlets. Named slots are passed with a slot="name" attribute on direct child nodes. Wrapper components can forward parent slot content to nested layouts with direct child <slot /> and <slot name="..." /> nodes. Imported GSX layout packages work the same way; the compiler resolves them through normal Go import paths.

Safety Model

Default behavior:

  • text expressions are HTML-escaped
  • dynamic attribute values are HTML-escaped
  • boolean attributes are emitted safely
  • indentation-only whitespace is removed predictably

Trusted raw HTML is explicit:

<raw html={runtime.HTML("<strong>trusted</strong>")} />

Normal {expr} output never bypasses escaping, even if the value is runtime.HTML.

See docs/escaping.md.

CLI

Build and generate:

gsx generate .
gsx build .
gsx check .
gsx watch --build .
gsx init --module example.com/myapp ./myapp

Notes:

  • generate stores package fingerprints in .gsx/cache.json and skips unchanged packages
  • watch uses fsnotify with debouncing instead of polling

Formatting and linting:

gsx fmt --write .
gsx fmt --check .
gsx lint .

See docs/cli.md.

Publishing

This repository is configured for the GitHub module path github.com/jlcsoftgenie/gsx. See docs/publishing.md for the exact push/tag flow.

Examples

Benchmarks

Measured with go test -bench=. -benchmem ./benchmarks on Linux amd64, Intel i7-10700KF:

Benchmark ns/op B/op allocs/op
BenchmarkGSXSimple 486.5 528 6
BenchmarkHTMLTemplateSimple 2027 896 22
BenchmarkGomponentsSimple 1748 1288 30
BenchmarkGSXList 42191 39184 412
BenchmarkGSXNestedLayouts 42117 39216 414
BenchmarkHTMLTemplateList 370383 106869 3629
BenchmarkGomponentsList 149412 112201 2437

See docs/performance.md.

Repository Layout

Generated Output

Generated files:

  • live next to the .gsx source file
  • are named *.gsx.go
  • expose Render<Component> wrappers
  • expose Render<Component>WithSlots and GSX<Component>Slots for advanced composition
  • keep a small internal render signature for local component calls

Example:

func RenderUsersPage(w io.Writer, title string, users []User) error
func RenderUsersPageWithSlots(w io.Writer, slots GSXUsersPageSlots, title string, users []User) error

Development

Run the full suite:

go test ./...
go test -bench=. -benchmem ./benchmarks
go run ./cmd/gsx check .

Regenerate templates after editing examples or benchmarks:

go run ./cmd/gsx generate ./examples ./benchmarks

Migration

For migration guidance from html/template, see docs/migration-from-html-template.md.

License

MIT. See LICENSE.

Directories

Path Synopsis
cmd
gsx command
examples
admin command
basic command
crosspkg command
htmx command
layouts command
webserver command
internal
ast

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL