AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Datastar

skill-maragudk-skills-datastar · by maragudk

Guide for building interactive web UIs with Datastar and gomponents-datastar. Use this skill when adding frontend interactivity to Go web applications with Datastar attributes.

No reviews yet
0 installs
38 views
0.0% view→install

Install

$ agentstack add skill-maragudk-skills-datastar

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-maragudk-skills-datastar)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
6mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Datastar? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Datastar

Overview

Datastar is a lightweight frontend framework that enables backend-driven, interactive UIs through a hypermedia-first approach. It combines backend reactivity (similar to htmx) with frontend reactivity (like Alpine.js) using standard HTML data-* attributes.

When to Use This Skill

Use this skill when:

  • Adding frontend interactivity to server-rendered HTML
  • Building reactive UIs driven by backend state
  • Using Datastar with gomponents in Go applications
  • Working with Server-Sent Events (SSE) for real-time updates

Prerequisite: When using Datastar with Go, also use the gomponents skill for HTML component patterns.

Installation

Browser (CDN)

Go (gomponents-datastar)

go get maragu.dev/gomponents-datastar

Part 1: Datastar Fundamentals

Core Concepts

Signals

Signals are reactive state containers. When a signal's value changes, all dependent expressions automatically update.


    
    Increment
  • Signal names are prefixed with $ in expressions
  • Setting a signal to null or undefined removes it
  • Use dot-notation for nested signals: $user.name

DOM Patching

Datastar uses morphing to update only changed DOM parts while preserving state. The backend sends HTML fragments that patch into the existing page.

Attributes Reference

State Management

data-signals - Initialize reactive signals:

data-computed - Create derived read-only signals:

data-init - Run expressions when element loads:

Data Binding

data-text - Bind text content to an expression:

data-bind - Two-way binding for form elements:

data-show - Conditionally show/hide elements:

Only shown when true

Styling

data-class - Conditionally apply CSS classes:

data-style - Set inline styles dynamically:

data-attr - Set HTML attributes dynamically:

Submit

Events

data-on - Attach event listeners:

Click me

The evt variable references the event object.

data-on-intersect - Trigger when element enters viewport:

Loading...

data-on-interval - Run at regular intervals:

Timer: 

data-on-signal-patch - Execute when signals update:

DOM Control

data-ref - Create signal referencing DOM element:

data-ignore - Exclude element from Datastar processing:

Third-party widget here

data-ignore-morph - Keep Datastar active but skip morphing:

Preserve this DOM structure

data-preserve-attr - Preserve attributes during morphing:

Backend Actions

@get(), @post(), @put(), @patch(), @delete() - Send requests to backend:

Load
Submit

Modifiers

Modifiers extend attribute behavior using double-underscore syntax:

Timing Modifiers

  • __debounce / __debounce_500ms - Debounce execution
  • __throttle / __throttle_1s - Throttle execution
  • __delay / __delay_200ms - Delay execution

Event Modifiers

  • __prevent - Call preventDefault()
  • __stop - Call stopPropagation()
  • __capture - Use capture phase
  • __passive - Mark as passive listener
  • __once - Execute only once
  • __self - Only trigger if target is the element itself
  • __outside - Trigger when event occurs outside element
  • __window - Attach listener to window

Example with Modifiers


Track

Server-Sent Events (SSE)

Datastar uses SSE for streaming responses. The backend sends events with text/event-stream content type.

SSE Event Types

datastar-patch-elements - Patch HTML into the DOM:

event: datastar-patch-elements
data: elements Updated content

datastar-patch-signals - Update signal values:

event: datastar-patch-signals
data: signals {count: 42}

datastar-remove-elements - Remove elements by selector:

event: datastar-remove-elements
data: selector #old-element

Part 2: gomponents-datastar

Overview

gomponents-datastar provides Go functions that generate Datastar attributes as gomponents nodes. It integrates seamlessly with the gomponents library.

Import Convention

Use dot imports for a clean DSL:

import (
    . "maragu.dev/gomponents"
    . "maragu.dev/gomponents/html"
    data "maragu.dev/gomponents-datastar"
)

Note: The data alias is recommended for datastar.

For up-to-date API documentation, run:

go doc maragu.dev/gomponents-datastar

Function Reference

State Management

Signals - Initialize reactive signals:

data.Signals(map[string]any{
    "count": 0,
    "name":  "World",
})

Computed - Create computed signals (key-value pairs):

data.Computed("doubled", "$count * 2")

Init - Run expression on load:

data.Init("console.log('Component loaded')")

Data Binding

Text - Bind text content:

Span(data.Text("'Hello, ' + $name"))

Bind - Two-way form binding:

Input(Type("text"), data.Bind("$name"))

Show - Conditional visibility:

Div(data.Show("$isVisible"), Text("Shown when visible"))

Styling

Class - Conditional classes (key-value pairs):

data.Class("active", "$isActive", "error", "$hasError")

Style - Dynamic inline styles (key-value pairs):

data.Style("color", "$textColor", "opacity", "$opacity")

Attr - Dynamic attributes (key-value pairs):

data.Attr("disabled", "$isLoading", "aria-busy", "$isLoading")

Events

On - Attach event listeners:

data.On("click", "$count++")
data.On("click", "@post('/submit')", data.ModifierPrevent)
data.On("input", "$search = evt.target.value", data.ModifierDebounce)

OnIntersect - Viewport intersection:

data.OnIntersect("@get('/load-more')")

OnInterval - Periodic execution:

data.OnInterval("$elapsed++")

OnSignalPatch - React to signal changes:

data.OnSignalPatch("console.log('Updated')")

DOM Control

Ref - Reference DOM element:

data.Ref("$inputEl")

Ignore - Skip Datastar processing:

data.Ignore()

IgnoreMorph - Skip morphing only:

data.IgnoreMorph()

PreserveAttr - Preserve attributes during morph:

data.PreserveAttr("value", "checked")

Request Helpers

Indicator - Show loading state:

data.Indicator("$isLoading")

JSONSignals - Control which signals are sent:

data.JSONSignals(data.Filter{Include: "form.*"})
data.JSONSignals(data.Filter{Exclude: "internal.*"})

Modifiers

Use modifier constants with event functions:

// Timing
data.ModifierDebounce  // __debounce
data.ModifierThrottle  // __throttle
data.ModifierDelay     // __delay

// Event behavior
data.ModifierPrevent   // __prevent
data.ModifierStop      // __stop
data.ModifierCapture   // __capture
data.ModifierPassive   // __passive
data.ModifierOnce      // __once
data.ModifierSelf      // __self
data.ModifierOutside   // __outside
data.ModifierWindow    // __window

// Duration/threshold helpers
data.Duration(500 * time.Millisecond)  // __500ms
data.Threshold(0.5)                     // __threshold_0.5

Complete Example

package views

import (
    "net/http"

    . "maragu.dev/gomponents"
    . "maragu.dev/gomponents/html"
    ghttp "maragu.dev/gomponents/http"
    ds "maragu.dev/gomponents-datastar"
)

func CounterPage() Node {
    return HTML5(HTML5Props{
        Title:    "Counter",
        Language: "en",
        Head: []Node{
            Script(
                Type("module"),
                Src("https://cdn.jsdelivr.net/gh/starfederation/[email protected]/bundles/datastar.js"),
            ),
        },
        Body: []Node{
            Div(
                data.Signals(map[string]any{"count": 0}),

                H1(data.Text("'Count: ' + $count")),

                Button(
                    data.On("click", "$count++"),
                    Text("Increment"),
                ),

                Button(
                    data.On("click", "$count--"),
                    Text("Decrement"),
                ),

                Button(
                    data.On("click", "@post('/api/save')"),
                    Text("Save to Server"),
                ),
            ),
        },
    })
}

func SearchForm() Node {
    return Form(
        data.Signals(map[string]any{"query": "", "results": []any{}}),
        data.On("submit", "@get('/search?q=' + $query)", data.ModifierPrevent),

        Input(
            Type("text"),
            data.Bind("$query"),
            data.On("input", "@get('/search?q=' + $query)", data.ModifierDebounce, data.Duration(300*time.Millisecond)),
            Placeholder("Search..."),
        ),

        Div(
            ID("results"),
            data.Show("$results.length > 0"),
            data.Text("'Found ' + $results.length + ' results'"),
        ),
    )
}

SSE Handler Pattern

func handleSSE(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "text/event-stream")
    w.Header().Set("Cache-Control", "no-cache")
    w.Header().Set("Connection", "keep-alive")

    flusher, ok := w.(http.Flusher)
    if !ok {
        http.Error(w, "SSE not supported", http.StatusInternalServerError)
        return
    }

    // Patch HTML elements
    fmt.Fprintf(w, "event: datastar-patch-elements\n")
    fmt.Fprintf(w, "data: elements Updated!\n\n")
    flusher.Flush()

    // Update signals
    fmt.Fprintf(w, "event: datastar-patch-signals\n")
    fmt.Fprintf(w, "data: signals {\"count\": 42}\n\n")
    flusher.Flush()
}

Tips

  1. Signal naming: Use $ prefix in expressions, not in Go code
  2. Avoid conflicts: Use data.Text() for Datastar text binding, gomponents Text() for static content
  3. Modifiers: Chain multiple modifiers: data.On("click", "...", data.ModifierPrevent, data.ModifierOnce)
  4. SSE IDs: Elements patched via SSE need matching id attributes
  5. Morphing: Datastar preserves form input state during DOM updates by default

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.