docs/comparison/gofr-vs-echo/page.md
{% answer %} Echo is a clean, ergonomic HTTP framework with a polished API and a good middleware curation — well suited for HTTP APIs where you want to compose your own production stack. GoFr has a wider scope: alongside HTTP routing it bundles OpenTelemetry tracing, Prometheus metrics, datasource clients, gRPC, GraphQL, WebSockets, Pub/Sub, migrations, cron, and a resilient service-to-service HTTP client. Two different scopes; pick the one that matches your project. {% /answer %}
c.JSON, c.Bind, group routing, middleware composition feel polished.net/http-based benchmarks.| Concern | Echo | GoFr |
|---|---|---|
| HTTP routing & middleware | Yes | Yes |
| OpenTelemetry tracing | Via middleware library | Built in |
| Prometheus metrics | Via middleware library | Built in |
| Structured logging with request context | Via library | Built in |
| Database clients (MySQL, Mongo, Redis, etc.) | Bring your own | 15+ built in, auto-instrumented |
| gRPC server | Run separately | Built in |
| GraphQL | Bring your own (gqlgen) | Built in |
| Pub/Sub | Bring your own (Kafka, NATS) | Built in |
| Cron jobs | Bring your own | Built in |
| Database migrations | Bring your own (golang-migrate) | Built in |
| Service-to-service HTTP w/ circuit breaker | Bring your own | Built in |
| RBAC | Build it | Config-driven |
| Health endpoints | Define manually | Auto-exposed at /.well-known/health |
Echo:
package main
import "github.com/labstack/echo/v4"
func main() {
e := echo.New()
e.GET("/hello", func(c echo.Context) error {
return c.JSON(200, map[string]string{"message": "Hello, world"})
})
e.Start(":8000")
}
GoFr:
package main
import "gofr.dev/pkg/gofr"
func main() {
app := gofr.New()
app.GET("/hello", func(c *gofr.Context) (any, error) {
return "Hello, world", nil
})
app.Run()
}
{% faq %}
{% faq-item question="Does GoFr have an equivalent of Echo's grouped routes?" %}
GoFr does not have a one-line Group equivalent. Replicate it by composing handlers with shared helpers and registering middleware globally with app.UseMiddleware.
{% /faq-item %}
{% faq-item question="Can I migrate Echo handlers to GoFr?" %}
The mental model translates well: echo.Context.JSON(200, x) becomes return x, nil. Bind, path params, and query params have direct equivalents on gofr.Context.
{% /faq-item %}
{% /faq %}