GoSPA (Go Spa and Go S-P-A are the only valid pronunciations) brings Svelte-like reactive primitives (Runes, Effects, Derived) to the Go ecosystem. It is a high-performance framework for building reactive SPAs with Templ, Fiber, file-based routing, and real-time state synchronization.
Rune, Derived, Effect primitives that work exactly like Svelte 5..gospa) with scoped CSS and Go-based logic..templ and .gospa files.go-json and optional MessagePack for minimal overhead.go.mod; use a current stable toolchain)esbuild, but Bun remains the recommended choice for maximum performance.JWT_SECRET: Ensure this environment variable is set for production authentication contexts (when using the Auth plugin).go install github.com/aydenstechdungeon/gospa/cmd/gospa@latest
or
go run github.com/aydenstechdungeon/gospa/cmd/gospa@latest
gospa create myapp
cd myapp
go mod tidy
gospa doctor
gospa dev
or
go run github.com/aydenstechdungeon/gospa/cmd/gospa@latest create myapp
cd myapp
go mod tidy
go run github.com/aydenstechdungeon/gospa/cmd/gospa@latest doctor
go run github.com/aydenstechdungeon/gospa/cmd/gospa@latest dev
For local client/runtime tooling, Bun is strongly preferred. The GoSPA CLI provides fallbacks for
pnpmandnpmusingesbuild, but Bun's integrated bundler is the authoritative development target.
// islands/Counter.gospa
<script lang="go">
var count = $state(0)
func increment() { count++ }
</script>
<template>
<button on:click={increment}>
Count is {count}
</button>
</template>
<style>
button { padding: 1rem; border-radius: 8px; }
</style>
GoSPA automatically compiles this to a reactive Templ component and a TypeScript hydration island.
| Feature | GoSPA | HTMX | Alpine | SvelteKit | MoonZoon |
|---|---|---|---|---|---|
| Language | Go | HTML | JS | JS/TS | Rust |
| Runtime | ~15KB | ~14KB | ~15KB | Varies | ~27KB |
| App Speed | Very High | High | High | Very High | Very High |
| DX Speed | High | Very High | Very High | High | Moderate |
| Reactivity | ✅ | ❌ | ✅ | ✅ | ✅ |
| WS Sync | ✅ | ❌ | ❌ | ✅ | ✅ |
| File Routing | ✅ | ❌ | ❌ | ✅ | ❌ |
| Type Safety | ✅ | ❌ | ❌ | ✅ | ✅ |
GoSPA Docs page (gospa.onrender.com - free hosting)
SvelteKit Docs page (svelte.dev/docs/kit/introduction)
Start from gospa.ProductionConfig() and tighten only what your app needs:
config := gospa.ProductionConfig()
config.AllowedOrigins = []string{"https://example.com"}
config.AppName = "myapp"
For prefork deployments, add external Storage and PubSub backends so state and realtime traffic stay consistent across workers.
Dynamic HTML (data-bind="html:*" and stream HTML chunks) is escaped by default in the runtime. If you need to render raw HTML, only use trusted server-controlled content.
Explore the full GoSPA documentation:
Source of truth policy: docs/** is canonical; website docs pages (website/routes/docs/**) must mirror this content and route taxonomy.
When in doubt, update docs/README.md first, then sync website routes and search index.
Reactive Primitives - Rune, Derived, Effect, and EffectScope.
State Management - Server-to-client state synchronization.
File-Based Routing - Layouts, pages, and rendering strategies.
Route Parameters - Dynamic route segments.
Remote Actions - Type-safe RPC between client and server.
WebSocket & Real-time - High-performance state sync.
Server-Sent Events - Lightweight real-time notifications.
Plugin Architecture - Extending the framework.
DevTools & Debugging - Error overlays and HMR.
Client Runtime - Tiered runtime internals.
API Reference - Fiber and Client API details.
Refused to execute inline script or Refused to load the script.'nonce-{nonce}', or custom inline/module scripts are missing the per-request nonce.cspPolicy := "default-src 'self'; script-src 'self' 'nonce-{nonce}'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' wss: https:; frame-ancestors 'none'; base-uri 'self'; form-action 'self';"
app.Fiber.Use(gospafiber.SecurityHeadersMiddleware(cspPolicy))
<script type="module" nonce={ gospatempl.GetNonce(ctx) }>
// custom client bootstrap code
</script>
Use the same nonce source (gospatempl.GetNonce(ctx)) for every custom inline or module script in your layout.
Building accessible SPAs is a first-class citizen in GoSPA:
GoSPA.announce("Message") to trigger screened reader notifications.We welcome contributions! Please see our Contributing Guide.
GoSPA is licensed under the Apache-2.0 license.