Install
$ agentstack add skill-castle-x-skills-x-go-embedded-spa ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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 No
- ✓ 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.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
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 →About
Go Embedded SPA
Overview
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.
Core Benefits
| 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 Structure
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
Implementation Steps
Step 1: Create embed.go
Create site/embed.go to declare embed directive. See references/embed.md for complete code.
Key points:
- Use
//go:embed all:distto embed all files including hidden files - Use
fs.Sub()to removedist/prefix
Step 2: Create Static File Server
Create pkg/siteserver/siteserver.go. See references/siteserver.md for complete implementation using Go standard net/http.
Core logic:
- Pre-load
index.htmlfor SPA fallback - Create
http.FileServerfrom embed.FS - Detect static resources by file extension
- Return
index.htmlfor SPA routes (no file extension)
Step 3: Application Integration
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.
Step 4: Development
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.
Step 5: Build for Production
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/)
Step 6: Cross-Platform Build
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
Request Handling Flow
Browser Request
│
▼
┌─────────────────────────────────────┐
│ http.ServeMux Route Matching │
│ ├── /apis/* → API Handler │
│ └── Others → Static Handler │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Static Handler │
│ ├── Has extension → serve file │
│ └── No extension → return index.html│
└─────────────────────────────────────┘
Caching Strategy
| Path | Cache-Control | Reason | |------|---------------|--------| | /assets/* | max-age=31536000, immutable | Files have hash in name | | /index.html | no-cache | Entry must be fresh |
Container Deployment
Minimal Dockerfile:
FROM scratch
COPY app /app
ENTRYPOINT ["/app"]
Troubleshooting
- Empty dist error → Run
make build-webbeforemake build-backend - Static files 404 → Check
//go:embed all:distpath relative to embed.go - API not matching → Register API routes BEFORE wrapping with siteserver
- SPA routes 404 → Verify handler returns index.html for non-file paths
References
go-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 build
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: castle-x
- Source: castle-x/skills-x
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.