Skip to content

Yacobolo/datastar-templ

Repository files navigation

datastar-templ

Type-safe Datastar attribute helpers for templ templates.
Go Reference Go Report Card License: MIT CI Status

datastar-templ mascot


datastar-templ is a Go library that provides compile-time type safety for Datastar attributes in templ templates. It bridges the gap between Go's templ templating system and Datastar's hypermedia framework, enabling you to build reactive web applications with full IDE autocomplete and type checking.

Features

  • Type-Safe: Compile-time checks for Datastar attributes with full IDE support
  • High Performance: Optimized with sync.Pool and precise capacity allocation (~200-300ns/op)
  • Complete Coverage: 60+ DOM events, HTTP actions, signals, and modifiers
  • templ Integration: Native templ.Attributes for seamless template usage

Installation

go get github.com/yacobolo/datastar-templ

Tested with Datastar 1.0.0-RC.7. Get started with Datastar.

Development

This project uses Task for development commands:

# Install Task (if not already installed)
brew install go-task/tap/go-task  # macOS
# or: go install github.com/go-task/task/v3/cmd/task@latest

# Common commands
task test              # Run all tests
task test:coverage     # Show test coverage
task bench             # Run performance benchmarks
task check             # Format, vet, and test
task --list            # See all available commands

See Taskfile.yml for the complete list of available tasks.

Usage

Import the package (commonly aliased as ds):

import ds "github.com/yacobolo/datastar-templ"

Quick Start Example

templ TodoApp() {
    <div { ds.Signals(
        ds.JSON("todos", []Todo{}),
        ds.String("newTodo", ""),
        ds.String("filter", ""),
    )... }>
        // Data binding
        <input 
            type="text"
            { ds.Bind("newTodo")... }
            placeholder="New todo"
        />
        
        // Event handlers with modifiers + SSE actions
        <button { ds.OnClick(
            ds.Post("/todos"),
            ds.ModDebounce,
            ds.Ms(300),
        )... }>
            Add Todo
        </button>
        
        // Conditional rendering + merging attributes
        <div { ds.Merge(
            ds.Show("$todos.length > 0"),
            ds.Class(ds.Pair("active", "$filter !== ''")),
        )... }>
            <span { ds.Text("$todos.length + ' items'")... }></span>
        </div>
        
        // Event handlers
        <input 
            type="search"
            { ds.Bind("filter")... }
            { ds.OnInput(
                ds.Get("/search?q=$filter"),
                ds.ModDebounce,
                ds.Ms(300),
            )... }
        />
    </div>
}

Type-Safe Helpers

datastar-templ provides type-safe helpers that eliminate runtime errors and provide clear API semantics:

Signal Helpers (for data transformation):

ds.Signals(
    ds.Int("count", 0),           // Converts int to string
    ds.String("message", "Hello"), // Adds quotes for JavaScript
    ds.Bool("isOpen", true),       // Formats boolean
    ds.Float("price", 19.99),      // Formats float
    ds.JSON("user", userData),     // Marshals complex types
)

Pair Helper (for expression bindings):

// Use ds.Pair() for all attribute bindings
ds.Class(
    ds.Pair("hidden", "$isHidden"),
    ds.Pair("font-bold", "$isBold"),
)

ds.Computed(
    ds.Pair("total", "$price * $qty"),
)

ds.Attr(
    ds.Pair("disabled", "$loading"),
    ds.Pair("title", "$tooltip"),
)

ds.Style(
    ds.Pair("color", "$textColor"),
    ds.Pair("display", "$visible ? 'block' : 'none'"),
)

// Or use ds.P() shorthand for brevity
ds.Class(ds.P("btn-primary", "$isMain"))

Why two different helpers?

  • Signal helpers (Int, String, etc.) transform Go values into JavaScript-compatible strings
  • Pair helper (Pair or P) simply pairs keys with expressions - no transformation needed

API Overview

See the Go package documentation for the complete API reference including:

  • Signal Helpers: Int(), String(), Bool(), Float(), JSON() for type-safe data transformation
  • Pair Helper: Pair() (or P()) for unified key-value expression bindings
  • 60+ Event Handlers: OnClick, OnInput, OnSubmit, OnKeyDown, etc.
  • HTTP Actions: Get, Post, Put, Patch, Delete with options
  • Signal Management: Signals, Computed, Bind, SignalKey
  • DOM Helpers: Text, Show, Class, Style, Attr
  • Modifiers: Debounce, Throttle, Once, Passive, Capture, etc.
  • Watchers: OnIntersect, OnInterval, OnSignalPatch
  • Utilities: Merge, Ref, Indicator, Init, Effect

Performance

The library is highly optimized using:

  • sync.Pool for builder reuse across requests
  • Precise capacity allocation to avoid buffer reallocation
  • Direct string building instead of JSON marshaling for primitives

Benchmark results (Apple M2):

BenchmarkSignals/simple-8      203.0 ns/op    392 B/op    5 allocs/op
BenchmarkClass/single-8        143.0 ns/op    376 B/op    4 allocs/op
BenchmarkComputed/single-8     170.2 ns/op    384 B/op    4 allocs/op

The implementation is only ~1.7x slower than raw inline fmt.Sprintf, while providing:

  • ✅ Type safety at compile time
  • ✅ Consistent API across all attributes
  • ✅ Better maintainability
  • ✅ No runtime reflection

Development

Run tests:

go test ./...

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details


DatastartemplAPI Reference

About

Type-safe Datastar attribute helpers for templ templates

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors