Warning
Golpher has not reached a stable release yet. For production applications today, we recommend using one of the mature frameworks that inspire this project, such as Fiber, Gin, or the Go standard library directly with net/http.
A net/http-first Go microframework with Express/Fiber-like DX.
Explore the API docs »
Getting Started
·
Report Bug
·
Request Feature
Table of Contents
Golpher is a small Go web framework designed for teams that want modern routing ergonomics without giving up the standard library boundary.
It is inspired by the developer experience of Fiber, Express, Gin, and Zinc, while keeping core Go primitives at the center: http.Handler, http.ResponseWriter, *http.Request, request cancellation, observability middleware, and ordinary net/http deployment.
Golpher is built for applications that need framework convenience while remaining interoperable with the broader Go HTTP ecosystem. It supports the HTTP QUERY method (RFC 10008) for safe, idempotent queries with a request body.
- Standard-library native:
*golpher.Appimplementshttp.Handler. - Modern routing DX:
app.GET,app.POST,app.QUERY, route groups,:params,*wildcards. - Middleware chain: global, group, route, and stdlib
func(http.Handler) http.Handlermiddleware. - Interop by design: mount existing
http.Handlervalues withFromHTTPHandler. - HTTP/2 ready: works through Go's
net/httpTLS/ALPN support. - HTTP/3 future-proof: core stays transport-agnostic so an HTTP/3 adapter can be added later without breaking the API.
- Security-minded defaults: server timeouts,
Recover,BodyLimit, 1 MiB default request body limit, route freeze, and validation are present from the start. - RFC 10008 QUERY: first-class
app.QUERY/Group.QUERYwithContent-Typeenforcement. - Error masking: unknown errors produce generic
500responses by default; the original error reaches only the configured observer. - Response tracking: committed state, status code, bytes written, and opt-in body capture on every write path, including
net/httpadapters. - Lazy request body:
http.MaxBytesReaderwrapping on first read;Body()returns([]byte, error)and caches the result.
Golpher is early-stage. The core API is being shaped through spec-driven development and TDD. Expect rapid iteration before a stable v1.
Follow these steps to install Golpher and run a minimal application.
- Go 1.23.6 or newer.
Check your Go version:
go versionInstall the module in your Go project:
go get github.com/go-golpher/golpherThen import it:
import "github.com/go-golpher/golpher"package main
import (
"net/http"
"github.com/go-golpher/golpher"
)
func main() {
app := golpher.New()
app.Use(golpher.Recover())
app.Use(golpher.BodyLimit(2 << 20)) // 2 MB
app.GET("/", func(req *golpher.Request, res *golpher.Response) error {
return res.JSON(map[string]string{"message": "hello, golpher"})
})
app.GET("/users/:id", func(req *golpher.Request, res *golpher.Response) error {
return res.SetStatus(http.StatusOK).JSON(map[string]string{
"id": req.Param("id"),
})
})
// RFC 10008 QUERY method — safe, idempotent, carries a body.
app.QUERY("/search", func(req *golpher.Request, res *golpher.Response) error {
var query SearchInput
if err := req.BodyJSON(&query); err != nil {
return err
}
return res.JSON(searchResults)
})
if err := app.Listen(); err != nil {
log.Fatal(err)
}
}app.UseHTTP(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Powered-By", "golpher")
next.ServeHTTP(w, r)
})
})app.Handle(http.MethodGet, "/healthz", golpher.FromHTTPHandler(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("ok"))
}),
))For more examples, see the Documentation.
- Getting started
- Principles and architecture
- Routing
- QUERY method (RFC 10008)
- Middleware
- Request and response
- Error handling
- Interoperability with net/http
- Deployment and protocols
- Testing
- Quality
- Migration guide
| Change | Migration |
|---|---|
Handler, ContextHandlerFunc, RawHandlerFunc, Ctx, Context removed. Single HandlerFunc. |
Replace Handler/ContextHandlerFunc handlers with func(*Request, *Response) error. Replace RawHandlerFunc with FromHTTPHandlerFunc. |
App.Get/Post/Put/Patch/Delete (Handler variants), HandleCtx, HandleContext, Raw removed. |
Use App.Handle or the uppercase verb shorthands (GET, POST, ...) with HandlerFunc. |
Error callbacks receive (*Request, *Response, error). |
Update ErrorHandler and ErrorObserver signatures. |
res.Status(code) renamed to res.SetStatus(code). res.Status() now reports the effective status. |
Replace all res.Status(code) calls with res.SetStatus(code). |
Request.Body() returns ([]byte, error). |
Replace req.Body().Bytes() with req.Body(), req.Body().JSON(v) with req.BodyJSON(v). |
DisableResponseBodyCapture replaced by EnableResponseBodyCapture (default false). |
Remove DisableResponseBodyCapture; add EnableResponseBodyCapture: true if capture is needed. |
App.Listen() returns error. |
Handle the error: if err := app.Listen(); err != nil { ... }. |
App.Config, App.Router, App.ErrorHandler no longer exported. |
Supply configuration through AppConfig to New. |
Route/middleware registration after first ServeHTTP panics. |
Register all routes before serving. |
| Invalid, duplicate, or conflicting route patterns panic at registration. | Fix invalid patterns; see docs/routing.md. |
Unknown errors masked: generic 500 body. |
Use ErrorObserver to inspect original errors. |
| Default request body limit: 1 MiB. | Set MaxRequestBodyBytes to adjust or -1 to disable. |
req.NewError / ctx.NewError removed. |
Use ErrorGolpher{Code: status, Message: msg}. |
BodyLimit middleware is lazy (no eager read). |
Behaviour unchanged for calls through req.Body(). |
For detailed migration patterns, see docs/migration.md.
See ROADMAP.md for planned work and open issues for proposed features and known issues.
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make Golpher better, please fork the repository and create a pull request. You can also open an issue with the enhancement label.
- Fork the project.
- Create your feature branch (
git checkout -b feature/amazing-feature). - Commit your changes using Conventional Commits (
git commit -m 'feat: add amazing feature'). - Push to the branch (
git push origin feature/amazing-feature). - Open a pull request.
For project-specific guidance, see CONTRIBUTING.md.
Distributed under the MIT License. See LICENSE for more information.
Project Link: https://github.com/go-golpher/golpher
- Best-README-Template for the README structure.
- Fiber, Express, Gin, and Zinc for framework ergonomics inspiration.