gospa

package module
v0.1.7 Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

README

GoSPA

gospa1 128 gospa2 128

A Go framework for building reactive SPAs with server-side rendering. Brings Svelte-like reactivity to Go using Fiber and Templ.

-# Pushing to master/main will stop once framework is stable or if other people start working on it.

Features

  • Reactive PrimitivesRune[T], Derived[T], Effect - Svelte-like reactivity in Go
  • File-Based Routing — SvelteKit-style routing for .templ files
  • WebSocket Sync — Real-time client-server state synchronization
  • Session Management — Secure session persistence with SessionStore and ClientStateStore
  • Type Safety — Compile-time template validation with Templ
  • Lightweight Runtime — ~11KB for the simple runtime, ~17KB for the full runtime with DOMPurify.
  • Remote Actions — Type-safe server functions callable directly from the client.
  • Error Handling — Global error boundaries, panic recovery, and error overlay in dev mode.
  • Security — Built-in CSRF protection, customizable CORS origins, and strict XSS prevention.
  • Rendering Modes — Mix SSR, SSG, ISR, and PPR per-page rendering strategies.

Installation

go get github.com/aydenstechdungeon/gospa

Quick Start

1. Initialize Project
go run github.com/aydenstechdungeon/gospa/cmd/gospa@latest create myapp

or from examples/:

go run ../cmd/gospa create myapp

from inside a examples project:

go run ../../cmd/gospa create myapp
mkdir myapp && cd myapp
go mod init myapp
2. Create Main File
// main.go
package main

import (
    "log"
    _ "myapp/routes" // Import routes to trigger init()
    
    "github.com/aydenstechdungeon/gospa"
)

func main() {
    app := gospa.New(gospa.Config{
        RoutesDir: "./routes",
        DevMode:   true,
        AppName:   "myapp",
    })

    if err := app.Run(":3000"); err != nil {
        log.Fatal(err)
    }
}
3. Create a Page
// routes/page.templ
package routes

templ Page() {
    <div data-gospa-component="counter" data-gospa-state='{"count":0}'>
        <h1>Counter</h1>
        <span data-bind="text:count">0</span>
        <button data-on="click:increment">+</button>
        <button data-on="click:decrement">−</button>
    </div>
}
4. Run
go run main.go

Core Concepts

State Modes

GoSPA supports two state management modes:

Local State (Client-Only)

State lives entirely in the browser. No server synchronization.

<div data-gospa-component="counter" data-gospa-local>
    <span data-bind="text:count">0</span>
    <button data-on="click:increment">+</button>
</div>
Synced State (Client-Server)

State synchronizes across all connected clients via WebSocket.

// Server-side handler with broadcast
fiber.RegisterActionHandler("increment", func(client *fiber.WSClient, payload json.RawMessage) {
    GlobalCounter.Count++
    fiber.BroadcastState(hub, "count", GlobalCounter.Count)
})
Reactive Primitives
Rune[T] — Reactive State
count := state.NewRune(0)
count.Get()           // 0
count.Set(5)          // notifies subscribers
count.Update(func(v int) int { return v + 1 })
Derived[T] — Computed State
count := state.NewRune(5)
doubled := state.NewDerived(func() int {
    return count.Get() * 2
})
doubled.Get() // 10
Effect — Side Effects
cleanup := state.NewEffect(func() func() {
    fmt.Println("Count:", count.Get())
    return func() { fmt.Println("cleanup") }
})
defer cleanup()
File-Based Routing
routes/
├ root_layout.templ    → Base HTML shell
├ page.templ           → /
├ about/
│   └ page.templ       → /about
├ (auth)/              → Grouped routes
│   ├ layout.templ
│   ├ login/
│   │   └ page.templ   → /login
│   └ register/
│       └ page.templ   → /register
├ blog/
│   ├── layout.templ   → Layout for /blog/*
│   └ [id]/
│       └ page.templ   → /blog/:id
└ posts/
    └ [...rest]/
        └ page.templ   → /posts/* (catch-all)
Embedded Routes (Production)

For production, you can embed your routes into the binary using go:embed. This allows for a zero-dependency, single-binary distribution.

// prod.go
//go:embed routes/*
var embeddedRoutes embed.FS

// main.go
var routesFS fs.FS
if devMode {
    routesFS = os.DirFS("./routes") // Real files for hot-reloading
} else {
    // Use the embedded files for production
    sub, _ := fs.Sub(embeddedRoutes, "routes")
    routesFS = sub
}

app := gospa.New(gospa.Config{
    RoutesFS: routesFS,
    DevMode:  devMode,
    // ...
})
Client Runtime
// Initialize component
GoSPA.init({ wsUrl: 'ws://localhost:3000/_gospa/ws' })

// Reactive state
const count = new GoSPA.Rune(0)
const doubled = new GoSPA.Derived(() => count.get() * 2)

// Effects
new GoSPA.Effect(() => {
    console.log('Count:', count.get())
})

// DOM binding
GoSPA.bindElement('element-id', count)

// Navigation
GoSPA.navigate('/about')
GoSPA.prefetch('/blog')

// Transitions
GoSPA.fade(element, { duration: 300 })
Performance vs Security (Simple Runtime)

By default, the client runtime includes DOMPurify for robust XSS protection on dynamically bound templates. If you prefer a smaller bundle size and are comfortable with a less strictly-secured basic sanitizer, you can switch to the lightweight runtime using the configuration flag:

app := gospa.New(gospa.Config{
    // ...
    SimpleRuntime: true,
    // SimpleRuntimeSVGs: true, // ⚠️ Only enable for fully trusted content — allows SVG in sanitizer
})
Remote Actions

Remote Actions allow you to define type-safe server functions that can be invoked seamlessly from the client without manually managing HTTP endpoints.

import (
    "context"
    "github.com/aydenstechdungeon/gospa/routing"
)

// Register on server
routing.RegisterRemoteAction("saveData", func(ctx context.Context, input interface{}) (interface{}, error) {
    // Type assert input to access data
    data, ok := input.(map[string]interface{})
    if !ok {
        return nil, errors.New("invalid input")
    }
    
    // Process data securely on the server
    id, _ := data["id"].(float64) // JSON numbers parse as float64
    
    return map[string]interface{}{
        "status": "success",
        "id":     int(id),
    }, nil
})

// Configure endpoint restrictions
app := gospa.New(gospa.Config{
    RemotePrefix:       "/api/rpc",
    MaxRequestBodySize: 1024 * 1024, // Limit body to 1MB
})
// Call from client
import { remote } from '@gospa/runtime';

const result = await remote('saveData', { id: 123 });

if (result.ok) {
    console.log('Success:', result.data);
} else {
    console.error('Error:', result.error, 'Code:', result.code);
    // Handle specific error codes programmatically
    if (result.code === 'ACTION_NOT_FOUND') {
        console.error('Action does not exist');
    }
}
Application Security

GoSPA comes with secure defaults, but robust configurations exist for production use to secure cross-origin requests and mitigate CSRF attacks:

app := gospa.New(gospa.Config{
    // ...
    AllowedOrigins: []string{"https://myapp.com", "https://api.myapp.com"},
})

CSRF protection requires two middlewares — one to issue the token cookie, one to validate it:

app.Fiber.Use(fiber.CSRFSetTokenMiddleware()) // issues csrf_token cookie on GET
app.Fiber.Use(fiber.CSRFTokenMiddleware())    // validates X-CSRF-Token header on POST/PUT/DELETE

Setting EnableCSRF: true alone is not sufficient — you must wire both middlewares.

Rendering Strategies

GoSPA supports four per-page rendering strategies:

Strategy When to Use
StrategySSR Auth-gated pages, per-user content, real-time data (default)
StrategySSG Fully static: marketing, docs, landing pages
StrategyISR Mostly static, refresh every N minutes (stale-while-revalidate)
StrategyPPR Static shell with dynamic inner sections (app dashboards)

Select a strategy per-page in your init():

import (
    "time"
    "github.com/aydenstechdungeon/gospa/routing"
)

func init() {
    // ISR: serve stale, revalidate in background every 5 minutes
    routing.RegisterPageWithOptions("/pricing", pricingPage, routing.RouteOptions{
        Strategy:        routing.StrategyISR,
        RevalidateAfter: 5 * time.Minute,
    })

    // PPR: cache nav/footer shell, re-render feed slot per-request
    routing.RegisterPageWithOptions("/dashboard", dashboardPage, routing.RouteOptions{
        Strategy:     routing.StrategyPPR,
        DynamicSlots: []string{"feed"},
    })
    routing.RegisterSlot("/dashboard", "feed", feedSlot)
}

Enable caching in your app config:

app := gospa.New(gospa.Config{
    CacheTemplates:         true,
    DefaultRenderStrategy:  routing.StrategyISR,  // app-wide fallback
    DefaultRevalidateAfter: 10 * time.Minute,
})

See docs/RENDERING.md for full documentation.

Partial Hydration

Opt out of reactivity for static content:

<div data-gospa-static>
    <h1>Static content — no bindings or event listeners</h1>
</div>
Transitions
<div data-transition="fade" data-transition-params='{"duration": 300}'>
    Fades in and out
</div>

<div data-transition-in="fly" data-transition-out="slide">
    Different enter/exit animations
</div>

Project Structure

myapp/
├ routes/              # Auto-routed .templ files
│   ├── root_layout.templ  # Root HTML shell (optional)
│   ├── layout.templ       # Root-level layout (optional)
│   ├── page.templ         # Home page
│   └ about/
│       └ page.templ
├ components/          # Reusable .templ components (optional)
├ lib/                 # Shared Go code (optional)
│   └ state.go         # App state
├ main.go
└ go.mod
Layout Files

GoSPA supports two types of layout files:

File Purpose Scope
root_layout.templ Outer HTML shell with <html>, <head>, <body> Entire application
layout.templ Nested layouts for sections Route segment and children

root_layout.templ — The outermost wrapper for your app. Must include the HTML document structure and GoSPA runtime script. There can only be one root layout (at routes/root_layout.templ). Requires routing.RegisterRootLayout().

layout.templ — Regular layouts that wrap pages within a route segment. You can have multiple nested layouts (e.g., routes/blog/layout.templ wraps all /blog/* pages).

routes/
├── root_layout.templ     # (Optional) Wraps entire app (Requires routing.RegisterRootLayout())
├── layout.templ          # Optional root-level layout
├── page.templ            # Home page (/)
├── about/
│   └── page.templ        # About page (/about)
└── blog/
    ├── layout.templ      # Wraps all blog pages
    └── page.templ        # Blog index (/blog)

If no root_layout.templ exists, GoSPA provides a minimal default HTML wrapper.

API Reference

See docs/API.md for complete API documentation. docs/llms/llms.txt docs/llms/llms-full.md

CLI

gospa create myapp    # Create new project
gospa generate        # Generate types and routes
gospa dev             # Development server with hot reload
gospa build           # Production build

Run any command with --help (e.g., gospa build --help) to see all available options and flags.

For more details, see the CLI Reference.

Plugin Ecosystem

GoSPA includes a powerful plugin system for extending build and development workflows.

Built-in Plugins
Plugin Description Commands
Tailwind CSS processing with Tailwind CSS v4 gospa add:tailwind (alias: at), gospa tailwind:build (alias: tb), gospa tailwind:watch (alias: tw)
PostCSS Advanced CSS with plugins (autoprefixer, typography, forms) gospa add:postcss (alias: ap), gospa postcss:build (alias: pb), gospa postcss:watch (alias: pw), gospa postcss:config (alias: pc)
Image Image optimization and responsive variants gospa image:optimize (alias: io), gospa image:clean (alias: ic), gospa image:sizes (alias: is)
Validation Form validation (Valibot client + Go validator server) gospa validation:generate (alias: vg), gospa validation:create (alias: vc), gospa validation:list (alias: vl)
SEO Sitemap, robots.txt, meta tags, structured data gospa seo:generate (alias: sg), gospa seo:meta (alias: sm), gospa seo:structured (alias: ss)
Auth OAuth2, JWT sessions, TOTP/OTP authentication gospa auth:generate (alias: ag), gospa auth:secret (alias: as), gospa auth:otp (alias: ao), gospa auth:backup (alias: ab), gospa auth:verify (alias: av)
QRCode QR code generation with customizable options Programmatic API only (no CLI commands)
Configuration

Plugins are configured in gospa.yaml:

plugins:
  tailwind:
    input: ./styles/main.css
    output: ./static/css/output.css
  image:
    input: ./images
    output: ./static/images
    formats: [webp, jpeg]
    sizes: [320, 640, 1280, 1920]
  auth:
    jwt_secret: ${JWT_SECRET}
    oauth:
      google:
        client_id: ${GOOGLE_CLIENT_ID}
        client_secret: ${GOOGLE_CLIENT_SECRET}
Plugin Hooks

Plugins integrate at key lifecycle points:

  • BeforeGenerate / AfterGenerate — Code generation
  • BeforeDev / AfterDev — Development server
  • BeforeBuild / AfterBuild — Production build
Creating Custom Plugins
package myplugin

import "github.com/aydenstechdungeon/gospa/plugin"

type MyPlugin struct{}

func (p *MyPlugin) Name() string { return "my-plugin" }
func (p *MyPlugin) Init() error { return nil }
func (p *MyPlugin) Dependencies() []plugin.Dependency {
    return []plugin.Dependency{
        {Name: "some-go-package", Type: plugin.DepGo},
        {Name: "some-bun-package", Type: plugin.DepBun},
    }
}
func (p *MyPlugin) OnHook(hook plugin.Hook, ctx map[string]interface{}) error {
    // Handle lifecycle hooks
    return nil
}
func (p *MyPlugin) Commands() []plugin.Command {
    return []plugin.Command{
        {Name: "my-plugin:run", Short: "mp", Description: "Run my plugin"},
    }
}

See docs/PLUGINS.md for complete plugin documentation.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                         Browser                              │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              GoSPA Runtime (<15KB*)                   │    │
│  │  ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ │    │
│  │  │  Rune   │ │ Derived  │ │ Effect  │ │WebSocket │ │    │
│  │  └────┬────┘ └────┬─────┘ └────┬────┘ └────┬─────┘ │    │
│  │       └───────────┴────────────┴──────────┘        │    │
│  │                      │                              │    │
│  │              ┌───────┴───────┐                     │    │
│  │              │  DOM Binder   │                     │    │
│  │              └───────────────┘                     │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
                               │
                               │ WebSocket / HTTP
                               ▼
┌─────────────────────────────────────────────────────────────┐
│                       Go Server                              │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                    Fiber App                         │    │
│  │  ┌──────────────┐  ┌──────────────┐                 │    │
│  │  │   Runtime    │  │   WebSocket  │                 │    │
│  │  │  Middleware  │  │   Handler    │                 │    │
│  │  └──────────────┘  └──────────────┘                 │    │
│  └─────────────────────────────────────────────────────┘    │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                  State Package                       │    │
│  │  ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ │    │
│  │  │  Rune   │ │ Derived  │ │ Effect  │ │  Batch   │ │    │
│  │  └─────────┘ └──────────┘ └─────────┘ └──────────┘ │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

Comparison

Feature GoSPA HTMX Alpine SvelteKit
Language Go HTML JS JS/TS
Runtime Size <15KB* ~14KB ~15KB Varies
SSR
SSG
ISR
PPR
Type Safety
WebSocket
File Routing
Reactivity

License

Apache License 2.0

Documentation

Overview

Package gospa provides a modern SPA framework for Go with Fiber and Templ. It brings Svelte-like reactivity and state management to Go.

Index

Constants

View Source
const Version = "0.1.7"

Version is the current version of GoSPA.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

type App struct {
	// Config is the application configuration.
	Config Config
	// Router is the file-based router.
	Router *routing.Router
	// Fiber is the underlying Fiber app.
	Fiber *fiberpkg.App
	// Hub is the WebSocket hub for real-time updates.
	Hub *fiber.WSHub
	// StateMap is the global state map.
	StateMap *state.StateMap
	// contains filtered or unexported fields
}

App is the main GoSPA application.

func New

func New(config Config) *App

New creates a new GoSPA application.

func (*App) Broadcast

func (a *App) Broadcast(message []byte)

Broadcast sends a message to all connected WebSocket clients.

func (*App) BroadcastState

func (a *App) BroadcastState(key string, value interface{}) error

BroadcastState broadcasts a state update to all connected WebSocket clients.

func (*App) Delete

func (a *App) Delete(path string, handlers ...fiberpkg.Handler)

Delete adds a DELETE route.

func (*App) Get

func (a *App) Get(path string, handlers ...fiberpkg.Handler)

Get adds a GET route.

func (*App) GetFiber

func (a *App) GetFiber() *fiberpkg.App

GetFiber returns the underlying Fiber app.

func (*App) GetHub

func (a *App) GetHub() *fiber.WSHub

GetHub returns the WebSocket hub.

func (*App) GetRouter

func (a *App) GetRouter() *routing.Router

GetRouter returns the file-based router.

func (*App) Group

func (a *App) Group(prefix string, handlers ...fiberpkg.Handler) fiberpkg.Router

Group creates a route group.

func (*App) Post

func (a *App) Post(path string, handlers ...fiberpkg.Handler)

Post adds a POST route.

func (*App) Put

func (a *App) Put(path string, handlers ...fiberpkg.Handler)

Put adds a PUT route.

func (*App) RegisterRoutes

func (a *App) RegisterRoutes() error

RegisterRoutes registers all scanned routes with Fiber.

func (*App) Run

func (a *App) Run(addr string) error

func (*App) RunTLS

func (a *App) RunTLS(addr, certFile, keyFile string) error

RunTLS starts the application with TLS on the given address.

func (*App) Scan

func (a *App) Scan() error

Scan scans the routes directory and builds the route tree.

func (*App) Shutdown

func (a *App) Shutdown() error

Shutdown gracefully shuts down the application.

func (*App) Static

func (a *App) Static(prefix, root string)

Static serves static files.

func (*App) Use

func (a *App) Use(middleware ...fiberpkg.Handler)

Use adds a middleware to the application.

type Config

type Config struct {
	// RoutesDir is the directory containing route files.
	RoutesDir string
	// RoutesFS is the filesystem containing route files (optional). Takes precedence over RoutesDir if provided.
	RoutesFS fs.FS
	// DevMode enables development features.
	DevMode bool
	// RuntimeScript is the path to the client runtime script.
	RuntimeScript string
	// StaticDir is the directory for static files.
	StaticDir string
	// StaticPrefix is the URL prefix for static files.
	StaticPrefix string
	// AppName is the application name.
	AppName string
	// DefaultState is the initial state for new sessions.
	DefaultState map[string]interface{}
	// EnableWebSocket enables WebSocket support.
	EnableWebSocket bool
	// WebSocketPath is the WebSocket endpoint path.
	WebSocketPath string
	// WebSocketMiddleware allows injecting session/auth middleware before WebSocket upgrade.
	WebSocketMiddleware fiberpkg.Handler

	// Performance Options
	// CompressState enables gzip compression of outbound WebSocket state payloads.
	// The client receives a { type:"compressed", data: "<base64>", compressed: true }
	// envelope and must decompress using the DecompressionStream browser API.
	CompressState bool
	// StateDiffing enables delta-only "patch" WebSocket messages for state syncs.
	// Only changed state keys are transmitted after the initial full snapshot.
	StateDiffing   bool
	CacheTemplates bool // Cache compiled templates (SSG only)
	SimpleRuntime  bool // Use lightweight runtime without DOMPurify (~6KB smaller)
	// SimpleRuntimeSVGs allows SVG elements in the simple runtime sanitizer.
	// WARNING: Only enable if your content is fully trusted and never user-generated.
	SimpleRuntimeSVGs bool

	// WebSocket Options — these values are passed directly to the client runtime's init() call.
	// Defaults: WSReconnectDelay=1s, WSMaxReconnect=10, WSHeartbeat=30s.
	WSReconnectDelay time.Duration // Initial reconnect delay (default 1s)
	WSMaxReconnect   int           // Max reconnect attempts (default 10)
	WSHeartbeat      time.Duration // Heartbeat ping interval (default 30s)

	// WSMaxMessageSize limits the maximum payload size for WebSocket messages (default 64KB).
	WSMaxMessageSize int
	// WSConnRateLimit sets the refilling rate in connections per second for WebSocket upgrades (default 0.2).
	WSConnRateLimit float64
	// WSConnBurst sets the burst capacity for WebSocket connection upgrades (default 5.0).
	WSConnBurst float64

	// Hydration Options
	// HydrationMode controls when components become interactive.
	// Supported values: "immediate" | "lazy" | "visible" | "idle" (default: "immediate").
	HydrationMode    string
	HydrationTimeout int // ms before force hydrate (used with "visible" and "idle" modes)

	// Serialization Options
	// StateSerializer overrides JSON for outbound WebSocket state serialization.
	// StateDeserializer overrides JSON for inbound WebSocket state deserialization.
	StateSerializer   StateSerializerFunc
	StateDeserializer StateDeserializerFunc

	// Routing Options
	DisableSPA bool // Disable SPA navigation completely
	// NOTE: SSR (global SSR mode) is planned but not yet implemented — currently all pages are SSR by default.
	SSR bool

	// Rendering Strategy Defaults
	// DefaultRenderStrategy sets the fallback strategy for pages that do not
	// explicitly call RegisterPageWithOptions. Defaults to StrategySSR.
	DefaultRenderStrategy routing.RenderStrategy
	// DefaultRevalidateAfter is the ISR TTL used when a page uses StrategyISR
	// but does not set RouteOptions.RevalidateAfter. Zero means revalidate every request.
	DefaultRevalidateAfter time.Duration

	// Remote Action Options
	MaxRequestBodySize int    // Maximum allowed size for remote action request bodies
	RemotePrefix       string // Prefix for remote action endpoints (default "/_gospa/remote")

	// Security Options
	AllowedOrigins []string // Allowed CORS origins
	EnableCSRF     bool     // Enable automatic CSRF protection (requires CSRFSetTokenMiddleware + CSRFTokenMiddleware)
	// SSGCacheMaxEntries caps the SSG/ISR/PPR page cache size. Oldest entries are evicted when full.
	// Default: 500. Set to -1 to disable eviction (unbounded, not recommended in production).
	SSGCacheMaxEntries int
	// SSGCacheTTL sets an expiration time for SSG cache entries. If zero, they never expire.
	SSGCacheTTL time.Duration

	// Prefork enables Fiber's prefork mode.
	// WARNING: If enabled without an external Storage/PubSub backend like Redis, in-memory state and WebSockets will be isolated per-process.
	Prefork bool

	// Storage defines the external storage backend for sessions and state. Defaults to in-memory.
	Storage store.Storage

	// PubSub defines the messaging backend for multi-process broadcasting. Defaults to in-memory.
	PubSub store.PubSub

	// IgnoredExtensions is a list of file extensions that the SPA router should ignore.
	// If nil, a default list of common non-HTML extensions is used.
	IgnoredExtensions []string

	// AppendIgnoredExtensions is a list of file extensions to add to the default list.
	AppendIgnoredExtensions []string
}

Config holds the application configuration.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default configuration.

type StateDeserializerFunc

type StateDeserializerFunc func([]byte, interface{}) error

StateDeserializerFunc defines a function for state deserialization

type StateSerializerFunc

type StateSerializerFunc func(interface{}) ([]byte, error)

StateSerializerFunc defines a function for state serialization

Directories

Path Synopsis
Package cli provides command-line interface tools for GoSPA.
Package cli provides command-line interface tools for GoSPA.
cmd
gospa command
Package main provides the gospa CLI tool.
Package main provides the gospa CLI tool.
gospa-gen command
Package main provides a code generator for GoSPA route registration.
Package main provides a code generator for GoSPA route registration.
Package component provides island architecture support for GoSPA.
Package component provides island architecture support for GoSPA.
starter
Package starter provides a library of reusable UI components for GoSPA applications
Package starter provides a library of reusable UI components for GoSPA applications
Package embed provides embedded static assets for the GoSPA framework.
Package embed provides embedded static assets for the GoSPA framework.
Package fiber provides error overlay functionality for development.
Package fiber provides error overlay functionality for development.
auth
Package auth provides authentication for GoSPA projects.
Package auth provides authentication for GoSPA projects.
image
Package image provides image optimization for GoSPA projects.
Package image provides image optimization for GoSPA projects.
postcss
Package postcss provides a PostCSS plugin for GoSPA with Tailwind CSS v4 support.
Package postcss provides a PostCSS plugin for GoSPA with Tailwind CSS v4 support.
qrcode
Package qrcode provides QR code generation for GoSPA applications.
Package qrcode provides QR code generation for GoSPA applications.
seo
Package seo provides SEO optimization for GoSPA projects.
Package seo provides SEO optimization for GoSPA projects.
tailwind
Package tailwind provides a Tailwind CSS v4 plugin for GoSPA.
Package tailwind provides a Tailwind CSS v4 plugin for GoSPA.
validation
Package validation provides form validation for GoSPA projects.
Package validation provides form validation for GoSPA projects.
Package routing provides file-based routing similar to SvelteKit.
Package routing provides file-based routing similar to SvelteKit.
generator
Package generator provides code generation for automatic route registration.
Package generator provides code generation for automatic route registration.
Package state provides batch update support for reactive primitives.
Package state provides batch update support for reactive primitives.
Package templ provides Templ integration helpers for GoSPA reactive bindings.
Package templ provides Templ integration helpers for GoSPA reactive bindings.
website module

Jump to

Keyboard shortcuts

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