Install any skill in seconds. Free to start, no credit card required.
Get Started Free →You are an expert in Chi, the lightweight, idiomatic Go HTTP router built on `net/http`. You help developers build composable HTTP services using Chi's middleware stack, route groups, URL parameters, sub-routers, and context-based request scoping — providing Express-like ergonomics while staying 100% compatible with Go's standard library.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 1% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 219% | 0% |
| case-20 | ✓→✗ | ▼ Worse | 112% | 0% |
| case-10 | ✓→✓ | = Same ✓ | 3% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 61% | 0% |
You are an expert in Chi, the lightweight, idiomatic Go HTTP router built on net/http. You help developers build composable HTTP services using Chi's middleware stack, route groups, URL parameters, sub-routers, and context-based request scoping — providing Express-like ergonomics while staying 100% compatible with Go's standard library.
gopackage main import ( "encoding/json" "net/http" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/go-chi/cors" ) func main() { r := chi.NewRouter() // Built-in middleware r.Use(middleware.Logger) r.Use(middleware.Recoverer) r.Use(middleware.RequestID) r.Use(middleware.RealIP) r.Use(middleware.Timeout(30 * time.Second)) r.Use(cors.Handler(cors.Options{ AllowedOrigins: []string{"https://app.example.com"}, AllowedMethods: []string{"GET", "POST", "PUT", "DELETE"}, })) // Public routes r.Get("/health", func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]string{"status": "ok"}) }) // Protected routes r.Route("/api", func(r chi.Router) { r.Use(authMiddleware) r.Route("/users", func(r chi.Router) { r.Get("/", listUsers) r.Post("/", createUser) r.Route("/{userID}", func(r chi.Router) { r.Use(userCtx) // Load user into context r.Get("/", getUser) r.Put("/", updateUser) r.Delete("/", deleteUser) r.Get("/posts", getUserPosts) }) }) }) http.ListenAndServe(":3000", r) } // Context middleware — load resource once, use in all sub-routes func userCtx(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { userID := chi.URLParam(r, "userID") user, err := db.FindUser(userID) if err != nil { http.Error(w, "user not found", 404) return } ctx := context.WithValue(r.Context(), "user", user) next.ServeHTTP(w, r.WithContext(ctx)) }) } func getUser(w http.ResponseWriter, r *http.Request) { user := r.Context().Value("user").(*User) json.NewEncoder(w).Encode(user) } func listUsers(w http.ResponseWriter, r *http.Request) { page := r.URL.Query().Get("page") users, _ := db.ListUsers(page) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(users) }
bashgo get -u github.com/go-chi/chi/v5
http.HandlerFunc; use any net/http middleware without adaptersr.Route("/prefix", func(r chi.Router) {...}) for scoped middleware and routescontext.WithValue; DRY across sub-routeschi.URLParam(r, "id") to extract route parameters; type-safe, explicitr.Mount("/admin", adminRouter()); clean separationmiddleware.Timeout to prevent slow handlers from blocking; returns 504 on timeoutOther measured skills in the registry, with their headline benchmark lift.