> go-echo
You are an expert in Echo, the high-performance, minimalist Go web framework. You help developers build REST APIs and web applications using Echo's optimized router, middleware chain, data binding, validation, template rendering, and WebSocket support — providing a clean API surface with excellent performance and comprehensive built-in middleware.
curl "https://skillshub.wtf/TerminalSkills/skills/go-echo?format=md"Echo — High-Performance Go Web Framework
You are an expert in Echo, the high-performance, minimalist Go web framework. You help developers build REST APIs and web applications using Echo's optimized router, middleware chain, data binding, validation, template rendering, and WebSocket support — providing a clean API surface with excellent performance and comprehensive built-in middleware.
Core Capabilities
Application Setup
package main
import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"https://app.example.com"},
AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete},
}))
e.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(20)))
// Routes
e.GET("/users", listUsers)
e.POST("/users", createUser)
e.GET("/users/:id", getUser)
// Groups with middleware
admin := e.Group("/admin", adminAuth)
admin.GET("/stats", getStats)
e.Logger.Fatal(e.Start(":3000"))
}
Handlers and Binding
type CreateUserRequest struct {
Name string `json:"name" validate:"required,min=2"`
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"gte=0,lte=130"`
}
func createUser(c echo.Context) error {
var req CreateUserRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "Invalid request")
}
if err := c.Validate(&req); err != nil {
return err
}
user, err := db.CreateUser(req.Name, req.Email, req.Age)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create user")
}
return c.JSON(http.StatusCreated, user)
}
func getUser(c echo.Context) error {
id := c.Param("id") // Path param
user, err := db.FindUser(id)
if err != nil {
return echo.NewHTTPError(http.StatusNotFound, "User not found")
}
return c.JSON(http.StatusOK, user)
}
func listUsers(c echo.Context) error {
page, _ := strconv.Atoi(c.QueryParam("page")) // Query param
if page < 1 { page = 1 }
users, total := db.ListUsers(page, 20)
return c.JSON(http.StatusOK, map[string]interface{}{
"data": users, "total": total, "page": page,
})
}
JWT Middleware
import "github.com/labstack/echo-jwt/v4"
// Configure JWT
e.Use(echojwt.WithConfig(echojwt.Config{
SigningKey: []byte(os.Getenv("JWT_SECRET")),
Skipper: func(c echo.Context) bool {
return c.Path() == "/health" || c.Path() == "/login"
},
}))
// Access claims in handler
func getProfile(c echo.Context) error {
token := c.Get("user").(*jwt.Token)
claims := token.Claims.(jwt.MapClaims)
userID := claims["user_id"].(string)
// ...
}
Installation
go get github.com/labstack/echo/v4
go get github.com/labstack/echo-jwt/v4
Best Practices
- Context methods — Use
c.Bind()for request parsing,c.JSON()for responses,c.Param()/c.QueryParam()for params - Groups for versioning —
e.Group("/api/v1")with per-group middleware (auth, rate limiting) - HTTPError for responses — Return
echo.NewHTTPError(status, message)for consistent error responses - Validator — Register a custom validator with
e.Validator; Echo calls it automatically afterBind() - Middleware chaining —
e.Use()for global, group-level, or per-route; Echo processes in order - Graceful shutdown — Use
e.Shutdown(ctx)with signal handling; drains active connections - Custom context — Extend
echo.Contextfor request-scoped data (user, logger, trace ID) - Static files —
e.Static("/assets", "public")for serving static files alongside API routes
> related_skills --same-repo
> zustand
You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.
> zod
You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.
> xero-accounting
Integrate with the Xero accounting API to sync invoices, expenses, bank transactions, and contacts — and generate financial reports like P&L and balance sheet. Use when: connecting apps to Xero, automating bookkeeping workflows, syncing accounting data, or pulling financial reports programmatically.
> windsurf-rules
Configure Windsurf AI coding assistant with .windsurfrules and workspace rules. Use when: customizing Windsurf for a project, setting AI coding standards, creating team-shared Windsurf configurations, or tuning Cascade AI behavior.