{"id":46666921,"url":"https://github.com/go-kruda/kruda","last_synced_at":"2026-04-02T16:19:04.993Z","repository":{"id":343061560,"uuid":"1164142219","full_name":"go-kruda/kruda","owner":"go-kruda","description":"High-performance, type-safe Go web framework with custom async I/O transport — 847K RPS plaintext","archived":false,"fork":false,"pushed_at":"2026-03-27T02:24:53.000Z","size":26760,"stargazers_count":17,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-27T05:04:26.585Z","etag":null,"topics":["epoll","generics","go","golang","high-performance","http","microservice","rest-api","type-safe","web-framework"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/go-kruda/kruda","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/go-kruda.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-22T17:48:04.000Z","updated_at":"2026-03-26T23:43:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/go-kruda/kruda","commit_stats":null,"previous_names":["go-kruda/kruda"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/go-kruda/kruda","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-kruda%2Fkruda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-kruda%2Fkruda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-kruda%2Fkruda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-kruda%2Fkruda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/go-kruda","download_url":"https://codeload.github.com/go-kruda/kruda/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-kruda%2Fkruda/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31309833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["epoll","generics","go","golang","high-performance","http","microservice","rest-api","type-safe","web-framework"],"created_at":"2026-03-08T19:08:39.343Z","updated_at":"2026-04-02T16:19:04.982Z","avatar_url":"https://github.com/go-kruda.png","language":"Go","readme":"# Kruda\n\nFast by default, type-safe by design.\n\n[![Go Version](https://img.shields.io/badge/Go-1.25+-00ADD8?logo=go)](https://go.dev)\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-kruda/kruda.svg)](https://pkg.go.dev/github.com/go-kruda/kruda)\n[![CI](https://github.com/go-kruda/kruda/actions/workflows/test.yml/badge.svg)](https://github.com/go-kruda/kruda/actions/workflows/test.yml)\n[![codecov](https://codecov.io/gh/go-kruda/kruda/graph/badge.svg?token=9HIGH8L2Q7)](https://codecov.io/gh/go-kruda/kruda)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\n## Why Kruda?\n\n- Typed handlers `C[T]` — body + param + query parsed into one struct, validated at compile time\n- Auto CRUD — implement `ResourceService[T]`, get 5 REST endpoints\n- Built-in DI — optional, no codegen, type-safe generics\n- Pluggable transport — Wing (Linux, epoll+eventfd), fasthttp, or net/http\n- Minimal deps — Sonic JSON (opt-out via `kruda_stdjson`), pluggable transport\n- AI-friendly — typed API + 21 examples = AI generates correct code on first try\n\n## Quick Start\n\n```bash\ngo get github.com/go-kruda/kruda\n```\n\n```go\npackage main\n\nimport (\n    \"github.com/go-kruda/kruda\"\n    \"github.com/go-kruda/kruda/middleware\"\n)\n\nfunc main() {\n    app := kruda.New()\n    app.Use(middleware.Recovery(), middleware.Logger())\n\n    app.Get(\"/ping\", func(c *kruda.Ctx) error {\n        return c.JSON(kruda.Map{\"pong\": true})\n    })\n\n    app.Listen(\":3000\")\n}\n```\n\n## Typed Handlers\n\n```go\ntype CreateUser struct {\n    Name  string `json:\"name\" validate:\"required,min=2\"`\n    Email string `json:\"email\" validate:\"required,email\"`\n}\n\ntype User struct {\n    ID    string `json:\"id\"`\n    Name  string `json:\"name\"`\n    Email string `json:\"email\"`\n}\n\nkruda.Post[CreateUser, User](app, \"/users\", func(c *kruda.C[CreateUser]) (*User, error) {\n    return \u0026User{ID: \"1\", Name: c.In.Name, Email: c.In.Email}, nil\n})\n```\n\n## Auto CRUD\n\n```go\nkruda.Resource[User, string](app, \"/users\", \u0026UserCRUD{db: db})\n// Registers: GET /users, GET /users/:id, POST /users, PUT /users/:id, DELETE /users/:id\n```\n\n## Dependency Injection\n\n```go\nc := kruda.NewContainer()\nc.Give(\u0026UserService{})\nc.GiveLazy(func() (*DBPool, error) { return connectDB() })\nc.GiveNamed(\"write\", \u0026DB{DSN: \"primary\"})\n\napp := kruda.New(kruda.WithContainer(c))\napp.Get(\"/users\", func(c *kruda.Ctx) error {\n    svc := kruda.MustResolve[*UserService](c)\n    return c.JSON(svc.ListAll())\n})\n```\n\n## Error Mapping\n\n```go\napp.MapError(ErrNotFound, 404, \"resource not found\")\nkruda.MapErrorType[*ValidationError](app, 422, \"validation failed\")\n```\n\n## Coming from Another Framework?\n\n| Concept | Kruda | Gin | Fiber | Echo | stdlib |\n|---------|-------|-----|-------|------|--------|\n| App | `kruda.New()` | `gin.Default()` | `fiber.New()` | `echo.New()` | `http.NewServeMux()` |\n| Route | `app.Get(\"/path\", h)` | `r.GET(\"/path\", h)` | `app.Get(\"/path\", h)` | `e.GET(\"/path\", h)` | `mux.HandleFunc(\"GET /path\", h)` |\n| Typed handler | `kruda.Post[In, Out](app, \"/path\", h)` | — | — | — | — |\n| Group | `app.Group(\"/api\")` | `r.Group(\"/api\")` | `app.Group(\"/api\")` | `e.Group(\"/api\")` | — |\n| Middleware | `app.Use(mw)` | `r.Use(mw)` | `app.Use(mw)` | `e.Use(mw)` | — |\n| Context | `*kruda.Ctx` | `*gin.Context` | `*fiber.Ctx` | `echo.Context` | `http.ResponseWriter, *http.Request` |\n| JSON response | `return \u0026obj, nil` | `c.JSON(200, obj)` | `c.JSON(obj)` | `c.JSON(200, obj)` | `json.NewEncoder(w).Encode(obj)` |\n| Path param | `c.Param(\"id\")` | `c.Param(\"id\")` | `c.Params(\"id\")` | `c.Param(\"id\")` | `r.PathValue(\"id\")` |\n| Query param | `c.Query(\"q\")` | `c.Query(\"q\")` | `c.Query(\"q\")` | `c.QueryParam(\"q\")` | `r.URL.Query().Get(\"q\")` |\n| Body binding | `c.Bind(\u0026v)` or `C[T].In` | `c.ShouldBindJSON(\u0026v)` | `c.BodyParser(\u0026v)` | `c.Bind(\u0026v)` | `json.NewDecoder(r.Body).Decode(\u0026v)` |\n| Auto CRUD | `kruda.Resource[T, ID](app, \"/path\", svc)` | — | — | — | — |\n| DI | `Container.Give()` / `MustResolve[T](c)` | — | — | — | — |\n\n\u003e Full migration guides: [Gin](docs/guide/coming-from-gin.md) · [Fiber](docs/guide/coming-from-fiber.md) · [Echo](docs/guide/coming-from-echo.md) · [stdlib](docs/guide/coming-from-stdlib.md)\n\n## Benchmarks\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/benchmark-chart.png\" alt=\"Kruda vs Fiber vs Actix Web benchmark\" width=\"800\"\u003e\n\u003c/p\u003e\n\nMeasured with `wrk -t4 -c256 -d5s` on Linux i5-13500 (8P cores), GOGC=400.\n\n| Test | Kruda (Go) | Fiber (Go) | Actix (Rust) | vs Fiber | vs Actix |\n|------|--:|--:|--:|--:|--:|\n| plaintext | **846,622** | 670,240 | 814,652 | +26% | +4% |\n| JSON | **805,124** | 625,839 | 790,362 | +29% | +2% |\n| db | **108,468** | 107,450 | 37,373 | +1% | +190% |\n| fortunes | 104,144 | **106,623** | 45,078 | -2% | +131% |\n\nWing transport uses raw `epoll` + `eventfd` on Linux — bypasses both fasthttp and net/http. macOS defaults to fasthttp.\n\n- See [`bench/reproducible/`](bench/reproducible/) for full source code of all 3 frameworks and reproduction steps\n\n## Documentation\n\n- [API Reference (pkg.go.dev)](https://pkg.go.dev/github.com/go-kruda/kruda)\n- [Examples](examples/) — 21 runnable examples\n- [Contributing](CONTRIBUTING.md)\n- [Security Policy](SECURITY.md)\n- [Benchmark Charts](https://go-kruda.github.io/kruda/benchmarks/)\n\n## AI Integration\n\nKruda includes a built-in [MCP](https://modelcontextprotocol.io/) server for AI coding assistants (Claude Code, Cursor, Copilot).\n\n```bash\n# Install CLI\ngo install github.com/go-kruda/kruda/cmd/kruda@latest\n\n# New projects — .mcp.json included automatically\nkruda new myapp\n\n# Existing projects\nkruda mcp init        # generates .mcp.json + .cursor/mcp.json\nkruda mcp --test      # verify it works\n```\n\n| Tool | Description |\n|------|-------------|\n| `kruda_new` | Scaffold a new project |\n| `kruda_add_handler` | Generate a typed handler with `C[T]` pattern |\n| `kruda_add_resource` | Generate a CRUD `ResourceService` |\n| `kruda_list_routes` | Scan source code and list all registered routes |\n| `kruda_suggest_wing` | Suggest Wing Feather hints for routes |\n| `kruda_docs` | Look up Kruda docs and code examples |\n\n## Security\n\nSee [SECURITY.md](SECURITY.md) for our responsible disclosure policy.\n\n### Security Hardening (Recommended)\n\n```go\nimport (\n    \"os\"\n    \"time\"\n\n    \"github.com/go-kruda/kruda\"\n    \"github.com/go-kruda/kruda/middleware\"\n    \"github.com/go-kruda/kruda/contrib/jwt\"\n    \"github.com/go-kruda/kruda/contrib/ratelimit\"\n)\n\napp := kruda.New(\n    kruda.WithBodyLimit(1024 * 1024), // 1MB body limit\n    kruda.WithReadTimeout(10 * time.Second),\n)\n\n// Rate limiting — 100 req/min per IP\napp.Use(ratelimit.New(ratelimit.Config{\n    Max: 100, Window: time.Minute,\n    TrustedProxies: []string{\"10.0.0.1\", \"10.0.0.2\"},\n}))\n\n// Stricter limit on auth endpoints\napp.Use(ratelimit.ForRoute(\"/api/login\", 5, time.Minute))\n\n// JWT authentication on protected routes\napi := app.Group(\"/api\").Guard(jwt.New(jwt.Config{\n    Secret: []byte(os.Getenv(\"JWT_SECRET\")),\n}))\n```\n\n### Contrib Modules\n\n| Module | Install | Description |\n|--------|---------|-------------|\n| [contrib/jwt](contrib/jwt/) | `go get github.com/go-kruda/kruda/contrib/jwt` | JWT sign, verify, refresh (HS256/384/512, RS256) |\n| [contrib/ws](contrib/ws/) | `go get github.com/go-kruda/kruda/contrib/ws` | WebSocket upgrade, RFC 6455 frames, ping/pong |\n| [contrib/ratelimit](contrib/ratelimit/) | `go get github.com/go-kruda/kruda/contrib/ratelimit` | Token bucket / sliding window rate limiting |\n| [contrib/session](contrib/session/) | `go get github.com/go-kruda/kruda/contrib/session` | Session middleware with pluggable store |\n| [contrib/compress](contrib/compress/) | `go get github.com/go-kruda/kruda/contrib/compress` | Response compression (gzip, deflate) |\n| [contrib/etag](contrib/etag/) | `go get github.com/go-kruda/kruda/contrib/etag` | ETag response caching |\n| [contrib/cache](contrib/cache/) | `go get github.com/go-kruda/kruda/contrib/cache` | Response cache (in-memory, Redis) |\n| [contrib/otel](contrib/otel/) | `go get github.com/go-kruda/kruda/contrib/otel` | OpenTelemetry tracing |\n| [contrib/prometheus](contrib/prometheus/) | `go get github.com/go-kruda/kruda/contrib/prometheus` | Prometheus metrics |\n| [contrib/swagger](contrib/swagger/) | `go get github.com/go-kruda/kruda/contrib/swagger` | Swagger UI HTML |\n\n### Pre-release Checklist\n\nRun vulnerability scan before every release:\n\n```bash\n# Install govulncheck (one-time)\ngo install golang.org/x/vuln/cmd/govulncheck@latest\n\n# Scan root module\ngovulncheck ./...\n\n# Scan Wing transport module\ncd transport/wing \u0026\u0026 govulncheck ./...\n```\n\nKruda core has minimal external dependencies (Sonic JSON, fasthttp). Use `kruda_stdjson` build tag to switch to stdlib JSON. Upgrade to the latest Go patch release for security fixes.\n\n**Minimum Go version for zero stdlib vulnerabilities:** go1.25.8+\n\n## Contributing\n\nContributions welcome. Please read the [Contributing Guide](CONTRIBUTING.md) before submitting a PR.\n\n## License\n\n[MIT](LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-kruda%2Fkruda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgo-kruda%2Fkruda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-kruda%2Fkruda/lists"}