skills/go-embedded-spa/SKILL.md
This skill provides guidance for implementing Go Embedded SPA architecture - embedding React/Vue/TSX frontend static resources into Go binary using go:embed directive. Use this skill when building self-contained single-binary applications, implementing SPA with Go backend, setting up cross-platform deployable full-stack projects, or configuring static file serving with Go standard library net/http.
npx skillsauth add castle-x/skills-x go-embedded-spaInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Go Embedded SPA is a technique that embeds frontend SPA (Single Page Application) static resources (React/Vue/TSX) into Go binary files using Go 1.16+ embed package, achieving single-binary full-stack deployment.
| Benefit | Description |
|---------|-------------|
| 🎯 Single File Deploy | One binary contains both frontend and backend, no nginx needed |
| 🌍 Cross-Platform | GOOS/GOARCH easily compiles for Linux/Mac/Windows |
| 📦 Zero Dependencies | Target machine needs no Node.js/npm, uses Go standard library only |
| 🚀 Container Friendly | Dockerfile only needs COPY + ENTRYPOINT |
| 🔒 Resource Security | Static resources compiled into binary, tamper-proof |
| ⚡ Fast Startup | No disk I/O for loading static files |
project/
├── go.mod
├── Makefile
├── site/ # Frontend project
│ ├── embed.go # Go embed directive
│ ├── src/ # React/Vue source
│ ├── dist/ # Build output (embedded)
│ ├── package.json
│ ├── vite.config.ts
│ └── index.html
├── pkg/
│ └── siteserver/ # Static file server
│ └── siteserver.go
└── cmd/
└── app/
└── main.go
Create site/embed.go to declare embed directive. See references/embed.md for complete code.
Key points:
//go:embed all:dist to embed all files including hidden filesfs.Sub() to remove dist/ prefixCreate pkg/siteserver/siteserver.go. See references/siteserver.md for complete implementation using Go standard net/http.
Core logic:
index.html for SPA fallbackhttp.FileServer from embed.FSindex.html for SPA routes (no file extension)package main
import (
"log"
"net/http"
"your-project/pkg/siteserver"
"your-project/site"
)
func main() {
mux := http.NewServeMux()
// 1. Register API routes FIRST
mux.HandleFunc("/apis/v1/health", healthHandler)
mux.HandleFunc("/apis/v1/data", dataHandler)
// 2. Wrap with static file server (as fallback)
handler := siteserver.WrapHandler(mux, site.DistDirFS)
log.Println("Server starting on :8080")
log.Fatal(http.ListenAndServe(":8080", handler))
}
Order is critical: API routes must be registered before static file server.
Recommended: Start both backend and frontend with one command:
make dev
# Backend: http://localhost:8080 (Go)
# Frontend: http://localhost:5173 (Vite with hot reload)
# API Proxy: /api/* -> localhost:8080
Press Ctrl+C to stop both servers.
Build order: frontend first, then backend
make build # Build both (frontend + backend)
# Or separately:
make build-web # npm run build → site/dist/
make build-backend # go build (embeds dist/)
make build-linux # Linux amd64
make build-linux-arm64 # Linux arm64
make build-macos # macOS Intel
make build-macos-arm64 # macOS Apple Silicon
make build-windows # Windows amd64
make build-all # All platforms
Browser Request
│
▼
┌─────────────────────────────────────┐
│ http.ServeMux Route Matching │
│ ├── /apis/* → API Handler │
│ └── Others → Static Handler │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Static Handler │
│ ├── Has extension → serve file │
│ └── No extension → return index.html│
└─────────────────────────────────────┘
| Path | Cache-Control | Reason |
|------|---------------|--------|
| /assets/* | max-age=31536000, immutable | Files have hash in name |
| /index.html | no-cache | Entry must be fresh |
Minimal Dockerfile:
FROM scratch
COPY app /app
ENTRYPOINT ["/app"]
make build-web before make build-backend//go:embed all:dist path relative to embed.gogo-dependencies.md - Go module dependencies (standard library only)embed.md - Complete embed.go implementationsiteserver.md - Static file server using Go standard net/httpvite-config.md - Vite configuration for development proxymakefile.md - Complete Makefile with cross-platform buildtools
Design specification for CLI TUI (Terminal User Interface). This skill provides comprehensive guidelines for implementing interactive terminal UI components, including page layout structure, color schemes, keyboard navigation, and multi-level navigation principles.
documentation
Guide for contributing new skills to the skills-x collection. This skill should be used when users want to add new open-source skills from external sources (like agentskills.io or anthropics/skills) to the skills-x repository. It covers the complete workflow from discovery to publishing.
tools
Use when designing or refining UIs that must be visually minimal, low-noise, and icon-forward while staying understandable for new users, especially when reducing text, consolidating controls, or streamlining dialogs, toolbars, search panels, or list results.
development
Integrate PocketBase as a Go library using the github.com/castle-x/goutils/pocketbase (gopb) package to build single-binary full-stack applications. Use when building Go applications that need user authentication, embedding PocketBase into Go binary, registering custom API routes, managing default users, serving embedded SPA frontend, or deploying single-binary applications. NOT for using PocketBase as a standalone separate process.