This guide is the operational and architectural reference for Fiber v3 (github.com/gofiber/fiber/v3), the Express-inspired Go web framework built on fasthttp. It is written for the engineers who deploy, secure, tune, and extend Fiber-based services, and for architects and contributors who need to understand how the framework is put together internally.
Where the User Guide shows how to build with Fiber, this guide covers the complete configuration surface, the request lifecycle, security hardening, performance tuning, the middleware internals, and the repository layout. Everything here is derived directly from the v3 source at commit dec796e.
1. Executive Summary
What Fiber is. A web framework — a library you import into a Go program, not a server you install and run. It provides an HTTP router, a request/response context, a binder, a centralized error model, and ~30 first-party middleware packages. It has no CLI, no daemon, and no configuration files: configuration is Go code (fiber.Config{} and fiber.ListenConfig{}).
What it is built on. fasthttp v1.71.0, a high-performance HTTP engine that minimizes allocations by pooling and reusing request/response/context objects. Fiber is a thin, ergonomic layer over fasthttp; most network and performance behavior ultimately comes from fasthttp's Server struct, which Fiber exposes via app.Server().
Operational shape. A Fiber service is a single Go binary. You scale it vertically with goroutine concurrency (the default), horizontally with multiple instances behind a load balancer, or with prefork (multiple processes on one host sharing a port). There is no built-in clustering, message broker, or shared cache — state that must be shared across instances or prefork workers belongs in an external store.
Key dependencies.
| Dependency | Version | Role |
|---|---|---|
github.com/valyala/fasthttp |
v1.71.0 | The HTTP server/client engine |
github.com/gofiber/schema |
v1.7.2 | Struct decoding for the query/form/header binders |
github.com/gofiber/utils/v2 |
v2.1.0 | Internal utilities (secure tokens, string helpers) |
github.com/google/uuid |
v1.6.0 | Request IDs |
github.com/shamaton/msgpack/v3 |
v3.1.2 | MessagePack encoding/decoding |
github.com/tinylib/msgp |
v1.6.4 | Generated MessagePack codecs for internal structs |
github.com/fxamacker/cbor/v2 |
v2.9.2 | CBOR encoding/decoding |
golang.org/x/crypto |
v0.52.0 | Cryptographic primitives (e.g. cookie encryption, bcrypt) |
github.com/andybalholm/brotli, klauspost/compress |
— | Brotli / gzip / zstd compression |
Minimum runtime: Go 1.25.0.
2. Architecture
Request lifecycle
┌──────────────────────────────────────────────────────────┐
client → │ fasthttp.Server (app.Server()) │
│ • connection pooling, keep-alive, read/write buffers │
│ • acquires a pooled *fasthttp.RequestCtx │
└───────────────────────────┬──────────────────────────────┘
│ RequestHandler (app.Handler())
▼
┌──────────────────────────────────────────────────────────┐
│ Fiber app │
│ 1. acquire fiber.Ctx from pool, wrap the RequestCtx │
│ 2. router match: method + path → handler chain │
│ (radix-style route tree, built at registration) │
│ 3. run middleware → handler chain via c.Next() │
│ 4. handler returns error? │
│ └─ yes → Config.ErrorHandler │
│ 5. write response into the pooled RequestCtx │
│ 6. release fiber.Ctx back to the pool │
└──────────────────────────────────────────────────────────┘
│
▼
response → client
The defining characteristic is object reuse: the fiber.Ctx and the underlying *fasthttp.RequestCtx are drawn from a sync.Pool and returned after the handler completes. This is what makes Fiber allocation-light, and it is the reason every value returned by Ctx is valid only within the handler. The timeout middleware interacts with this directly via c.Abandon()/c.ForceRelease() to keep a context alive past a timeout without corrupting the pool.
Core components
| Component | Source | Responsibility |
|---|---|---|
App |
app.go |
Top-level application: config, route registry, server lifecycle |
Config |
app.go |
All app-level settings (see §4) |
| Router | router.go, path.go |
Route tree, path parsing, parameter/constraint matching |
DefaultCtx |
ctx.go, req.go, res.go |
The request/response context (the Ctx interface implementation) |
| Binder | bind.go, binder/ |
Decodes URI/query/body/header/cookie into structs |
Group |
group.go |
Prefix + middleware scoping; sub-routers |
| Listener | listen.go |
Listen/Listener, ListenConfig, TLS, startup message |
| Prefork | prefork.go |
Multi-process serving on one port |
| Hooks | hooks.go |
Lifecycle callbacks (OnRoute, OnListen, OnShutdown, …) |
| Redirect | redirect.go |
Flash messages, redirect helpers |
| State / SharedState | state.go, shared_state.go |
In-process and storage-backed key/value state |
| Domain router | domain.go |
Hostname-scoped routing |
| Error model | error.go, errors_internal.go |
fiber.Error, predefined ErrXxx values |
| HTTP client | client/ |
fasthttp-backed outbound client (connection pools, hooks, cookie jar) |
| Logging facade | log/ |
Pluggable logger used by the framework and middleware |
| Middleware | middleware/* |
~30 first-party middleware packages (see §5) |
| Internal | internal/* |
Memory store, storage adapters, redaction, TLS test helpers |
Handler model
Fiber's native handler is fiber.Handler = func(c fiber.Ctx) error. The router also adapts, at registration time, several other shapes so they can be mixed freely:
- Express-style:
func(req fiber.Req, res fiber.Res) errorand 3-argument middleware forms with anextcallback. net/http:http.Handlerandhttp.HandlerFuncare accepted directly.- fasthttp: raw
fasthttp.RequestHandlercallbacks.
Adapted net/http handlers run with standard-library semantics and pay a compatibility cost; native fiber.Handler callbacks are the fastest path.
3. Requirements
| Requirement | Detail |
|---|---|
| Go toolchain | 1.25.0 or newer (hard requirement; Fiber uses unsafe) |
| OS | Linux, macOS, Windows. Prefork load-balancing is best on Linux (SO_REUSEPORT) |
| Architecture | Any Go-supported arch |
| External services | None required. Optional: Redis/other storage for shared middleware state |
| Build | Standard go build / go test; no codegen step needed by consumers |
Important
Because Fiber relies on
unsafefor zero-allocation optimizations, it may lag the very latest Go release. v3 is validated against Go 1.25+. Pin your toolchain accordingly.
4. Configuration Reference
Configuration is passed as a value to fiber.New(config ...Config). Listen-time options are passed to app.Listen(addr, config ...ListenConfig).
app := fiber.New(fiber.Config{
CaseSensitive: true,
StrictRouting: true,
ServerHeader: "Fiber",
AppName: "Test App v1.0.1",
})
fiber.Config — application settings
| Field | Type | Default | Description |
|---|---|---|---|
AppName |
string |
"" |
Application name shown in logs and the Server header startup banner. |
BodyLimit |
int |
4 * 1024 * 1024 |
Max request body size. Exceeding it returns 413. Also bounds Ctx.Body() decompression and MultipartForm() parsing. |
CaseSensitive |
bool |
false |
When true, /Foo ≠ /foo. |
StrictRouting |
bool |
false |
When true, /foo ≠ /foo/. |
Concurrency |
int |
256 * 1024 |
Max concurrent connections (maps to fasthttp.Server.Concurrency). |
ReadTimeout |
time.Duration |
0 (unlimited) |
Max time to read the full request including body. |
WriteTimeout |
time.Duration |
0 (unlimited) |
Max time to write the response. |
IdleTimeout |
time.Duration |
0 |
Keep-alive idle wait; falls back to ReadTimeout if zero. |
ReadBufferSize |
int |
4096 |
Per-connection read buffer; also caps max header size (raise for big cookies/URIs). |
WriteBufferSize |
int |
4096 |
Per-connection write buffer. |
DisableKeepalive |
bool |
false |
Close each connection after the first response. |
DisableHeaderNormalizing |
bool |
false |
Skip header-name normalization (conteNT-tYPE → Content-Type). |
DisableDefaultContentType |
bool |
false |
Omit the default Content-Type response header. |
DisableDefaultDate |
bool |
false |
Omit the Date response header. |
DisableHeadAutoRegister |
bool |
false |
Stop auto-registering a HEAD route per GET route. |
DisablePreParseMultipartForm |
bool |
false |
Treat multipart bodies as opaque; parse on demand. |
StreamRequestBody |
bool |
false |
Stream large request bodies; invoke the handler before the full body arrives. |
ReduceMemoryUsage |
bool |
false |
Trade CPU for lower memory. |
GETOnly |
bool |
false |
Reject all non-GET requests (anti-DoS for read-only servers). |
Immutable |
bool |
false |
Make all values returned by Ctx methods immutable (safe to retain). Has a performance cost. |
UnescapePath |
bool |
false |
URL-decode the path before routing, so routes match encoded characters. |
EnableIPValidation |
bool |
false |
Validate IPs in c.IP()/c.IPs() and return a single valid client IP. Small CPU cost. |
EnableSplittingOnParsers |
bool |
false |
Split query/body/header params on commas during binding. |
ErrorHandler |
ErrorHandler |
DefaultErrorHandler |
Central handler invoked when a handler returns an error. |
StructValidator |
StructValidator |
nil |
Validator run during binding. None by default — validation is skipped if unset. |
Views |
Views |
nil |
Template engine for c.Render(). Defaults to html/template behavior when nil. |
ViewsLayout |
string |
"" |
Global layout template name. |
PassLocalsToViews |
bool |
false |
Expose c.Locals() to the view engine. |
PassLocalsToContext |
bool |
false |
Also propagate StoreInContext values into the request context.Context. |
ServerHeader |
string |
"" |
Value for the Server response header (empty = not sent). |
ProxyHeader |
string |
"" |
Header to read the client IP from behind a proxy. Requires TrustProxy. |
TrustProxy |
bool |
false |
Enable trust of reverse-proxy headers (see §6). |
TrustProxyConfig |
TrustProxyConfig |
{} |
Which proxy IPs/ranges to trust (see §6). |
CompressedFileSuffixes |
map[string]string |
{"gzip":".fiber.gz","br":".fiber.br","zstd":".fiber.zst"} |
Suffixes for cached compressed files. |
MaxRanges |
int |
16 |
Max ranges parsed from a Range header. |
RequestMethods |
[]string |
DefaultMethods |
Customizable HTTP method set. |
RegexHandler |
any |
regexp.MustCompile |
Compiler for regex() route constraints (swap engines here). |
ColorScheme |
Colors |
DefaultColors |
Colors for startup output and some middleware. |
JSONEncoder / JSONDecoder |
utils.JSONMarshal / Unmarshal |
json.Marshal / Unmarshal |
Swap the JSON library. |
XMLEncoder / XMLDecoder |
— | xml.Marshal / Unmarshal |
Swap the XML library. |
CBOREncoder / CBORDecoder |
— | unimplemented stub | Provide a CBOR codec to enable CBOR. |
MsgPackEncoder / MsgPackDecoder |
— | unimplemented stub | Provide a MsgPack codec to enable MsgPack. |
Note
The CBOR and MsgPack encoders default to unimplemented stubs. You must wire in a real codec (or follow the framework's setup docs) before
c.CBOR()/c.MsgPack()and the corresponding binders work. JSON and XML work out of the box.
fiber.ListenConfig — listen-time settings
| Field | Type | Default | Description |
|---|---|---|---|
EnablePrefork |
bool |
false |
Spawn one process per CPU core on the same port. |
DisableStartupMessage |
bool |
false |
Suppress the ASCII banner and listen line. |
EnablePrintRoutes |
bool |
false |
Print every registered route on startup. |
ListenerNetwork |
string |
tcp4 |
tcp, tcp4, tcp6, or unix. Prefork supports only tcp4/tcp6. |
UnixSocketFileMode |
os.FileMode |
0770 |
Permissions for a Unix-domain-socket listener. |
GracefulContext |
context.Context |
nil |
Cancel this context to trigger graceful shutdown. |
ShutdownTimeout |
time.Duration |
10 * time.Second |
Max wait for graceful shutdown; 0 waits forever. |
BeforeServeFunc |
func(app *App) error |
nil |
Hook to inspect/mutate the app right before serving. |
ListenerAddrFunc |
func(addr net.Addr) |
nil |
Access the bound listener address. |
PreforkRecoverThreshold |
int |
max(1, GOMAXPROCS/2) |
Max child restarts before the prefork master exits with error. |
PreforkLogger |
PreforkLogger |
Fiber logger | Logger for the prefork process manager. |
CertFile / CertKeyFile |
string |
"" |
TLS certificate and private key paths. |
CertClientFile |
string |
"" |
Client CA for mTLS (only with CertFile/CertKeyFile). |
TLSConfig |
*tls.Config |
nil |
Full TLS control; when set, all other TLS fields are ignored. |
TLSConfigFunc |
func(*tls.Config) |
nil |
Customize the built TLS config (ignored if TLSConfig set). |
TLSMinVersion |
uint16 |
tls.VersionTLS12 |
Minimum TLS version. |
AutoCertManager |
*autocert.Manager |
nil |
ACME / Let's Encrypt automatic certificates. |
TLS precedence: TLSConfig wins and ignores CertFile/CertKeyFile/CertClientFile/AutoCertManager/TLSMinVersion/TLSConfigFunc. AutoCertManager cannot be combined with CertFile/CertKeyFile.
5. Middleware Internals
All first-party middleware live under middleware/<name>/ and follow the same pattern: a New(config ...Config) fiber.Handler constructor, a Config struct, and a ConfigDefault that configDefault() merges user overrides onto. Storage-backed middleware (limiter, cache, session, csrf, idempotency) default to an in-process memory store and accept any fiber.Storage implementation (e.g. a gofiber/storage Redis/Postgres driver) for shared/persistent state.
Selected middleware reference
cors — defaults that matter:
| Field | Default | Note |
|---|---|---|
AllowOrigins |
["*"] |
Allows all origins by default — override in production. |
AllowMethods |
GET, POST, HEAD, PUT, DELETE, PATCH |
|
AllowHeaders |
[] |
|
AllowCredentials |
false |
Cannot be true together with "*" origin. |
MaxAge |
0 |
Browser default (5s) when 0; negative disables caching. |
AllowPrivateNetwork |
false |
Private Network Access header support. |
limiter — fixed-window by default:
| Field | Default | Note |
|---|---|---|
Max |
5 |
Requests per window. |
Expiration |
1 * time.Minute |
Window length. |
KeyGenerator |
c.IP() |
Per-client key. |
LimitReached |
429 Too Many Requests |
|
LimiterMiddleware |
FixedWindow{} |
Also ships SlidingWindow. |
Storage |
in-memory (per process) | Use external storage under prefork/multi-instance. |
DisableHeaders |
false |
Emits X-RateLimit-* + Retry-After by default. |
csrf — defaults and a built-in safety check:
| Field | Default | Note |
|---|---|---|
CookieName |
"csrf_" |
|
CookieSameSite |
"Lax" |
|
CookieSecure |
false |
Set true in production. |
CookieHTTPOnly |
false |
Set true in production. |
IdleTimeout |
30 * time.Minute |
Token validity. |
Extractor |
extractors.FromHeader("X-Csrf-Token") |
Most secure default. |
KeyGenerator |
utils.SecureToken |
|
SingleUseToken |
false |
Caution
The CSRF middleware panics at startup if you configure an
Extractorthat reads the token from the same cookie used to store it — that configuration would completely defeat CSRF protection. It also logs a warning when you extract the token from the query string or a route param (URLs may be logged). Keep the default header extractor for APIs, or useextractors.FromForm("_csrf")for HTML forms.
Other notable middleware: helmet (security headers), encryptcookie (AES cookie value encryption, needs a 32-byte key), keyauth/basicauth (auth), idempotency (dedupe unsafe requests by key), healthcheck (liveness/readiness probes), pprof/expvar (diagnostics — keep them off public interfaces), compress (gzip/br/zstd/deflate), etag/cache (conditional/cached responses), proxy (reverse proxy), static (file serving), paginate, requestid, responsetime, hostauthorization, earlydata, sse, timeout, recover, logger, skip, rewrite, redirect, favicon, envvar, adaptor.
6. Security
Fiber gives you the primitives for a secure service, but several defaults favor developer convenience and must be hardened for production. The items below correspond to real, currently-tracked issues in the project.
Trusted proxies and client IP
By default c.IP() returns the TCP remote address. Behind a reverse proxy/CDN, you must opt in to header-based client IP and validate which proxies you trust — otherwise clients can spoof X-Forwarded-For to bypass IP-based controls.
app := fiber.New(fiber.Config{
TrustProxy: true,
ProxyHeader: fiber.HeaderXForwardedFor,
TrustProxyConfig: fiber.TrustProxyConfig{
Proxies: []string{"10.10.0.58", "192.168.0.0/24"}, // your proxies only
// or: Private: true / Loopback: true / LinkLocal: true / UnixSocket: true
},
})
TrustProxyConfig fields: Proxies (IPs/CIDRs), Loopback (127.0.0.0/8, ::1/128), Private (RFC1918 + fc00::/7), LinkLocal (169.254.0.0/16, fe80::/10), UnixSocket. When the remote IP is trusted, Fiber reads c.IP() from ProxyHeader, c.Scheme() from X-Forwarded-Proto (and siblings), and c.Hostname() from X-Forwarded-Host; untrusted peers fall back to the connection values. Enable EnableIPValidation if you need c.IP() to return a single validated IP rather than the raw header chain.
Warning
Setting
ProxyHeaderwithoutTrustProxyhas no effect. Both are required. Never enableTrustProxywith an unrestrictedTrustProxyConfigin a hostile network — that re-opens IP spoofing.
Cookie hardening checklist
The session and CSRF middleware ship with Secure=false and HTTPOnly=false cookies by default. For any HTTPS deployment:
- [ ] Session:
CookieSecure: true,CookieHTTPOnly: true, an appropriateCookieSameSite. - [ ] CSRF:
CookieSecure: true,CookieHTTPOnly: true. - [ ] Set explicit
cors.Config.AllowOrigins(never ship the"*"default to production). - [ ] If you set cookies manually, prefer
HTTPOnly: true,Secure: true,SameSite: "Lax"(or"Strict").
Important
Fiber forces
Secure: trueautomatically only forSameSite: "None"cookies. For all other cookies you are responsible for settingSecureandHTTPOnly.
Logging and injection
The logger middleware writes user-controlled values (path, headers, user agent) without sanitization, so untrusted input can inject control characters or forged lines into your logs. Sanitize or structure your log sink, and avoid logging raw user input into formats where newlines are significant.
Panics, timeouts, and resource leaks
- Panics are not recovered by default — always mount
recover.New(), or a single panic takes down the worker (or, under prefork, restarts a child and counts againstPreforkRecoverThreshold). - The timeout middleware works by abandoning the context and returning early while the handler goroutine continues; long-running handlers behind a timeout can accumulate in-flight goroutines/contexts under load. Bound the work itself (pass
c.Context()deadlines into downstream calls), don't rely on the timeout middleware alone to reclaim resources. - Background goroutines started by your handlers must not capture
c; they must usec.Context()and have a shutdown path.
Open redirects
Redirect().Back() falls back to a referer-derived target; validate redirect destinations against an allowlist rather than trusting Referer/user-supplied next parameters.
Prefork security
Prefork changes the port-ownership model from single-owner to multi-listener. On shared hosts a co-resident process could race for binds or receive a share of traffic (platform-dependent). Run prefork only within a single trust boundary, under a dedicated service account, ideally with container/VM isolation. If strict single-owner port semantics are required, do not use prefork.
Diagnostics exposure
pprof, expvar, and envvar middleware expose internal runtime data. Never mount them on a public interface — bind them to an internal admin port or guard them behind auth.
7. Performance Tuning
Fiber's speed comes from fasthttp and the pooled-context model. Tuning is mostly about not undoing those wins and about matching buffers/timeouts to your traffic.
-
Keep handlers allocation-light. Do not retain
Ctxvalues; copy only when necessary. LeaveImmutableoff unless you specifically need retained values — it adds per-call cost. -
Buffers. Raise
ReadBufferSizeif clients send large headers/cookies/URIs (it also caps max header size). RaiseWriteBufferSizefor large responses. -
Timeouts. The defaults are unlimited (
ReadTimeout/WriteTimeout= 0). Set them in production to bound slow-client and slow-loris exposure. -
Concurrency.
Concurrency(default 256K) caps simultaneous connections; tune withReduceMemoryUsageif memory-constrained. -
Direct fasthttp tuning. For knobs Fiber does not surface, reach the server directly:
app := fiber.New() app.Server().MaxConnsPerIP = 100 app.Server().MaxRequestsPerConn = 1000 -
Prefork for CPU-bound throughput on multi-core hosts. Each child runs effectively
GOMAXPROCS=1, reducing cross-core runtime overhead. Remember: no shared in-process memory between children — useapp.SharedState()or external storage. Distinguish processes withfiber.IsChild(). -
Compression (
compressmiddleware) trades CPU for bandwidth;SendFilecan cache compressed variants (Compress: true, suffixes fromCompressedFileSuffixes). -
Custom JSON codec. Swap in a faster JSON library via
Config.JSONEncoder/JSONDecoderif encoding dominates your profile.
The project tracks several performance issues worth knowing: storage-backed middleware (limiter, cache, session) share a global mutex that can serialize under high concurrency, and the binder allocates per-request maps. If you run at very high RPS with these middleware, benchmark them specifically and consider sharded/external storage.
8. Operations
Graceful shutdown
go func() {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt, syscall.SIGTERM)
<-sigint
if err := app.ShutdownWithTimeout(10 * time.Second); err != nil {
log.Printf("graceful shutdown failed: %v", err)
}
}()
if err := app.Listen(":3000"); err != nil {
log.Fatal(err)
}
Shutdown() waits indefinitely for connections to drain; ShutdownWithTimeout force-closes after the deadline; ShutdownWithContext ties drain to a context. Shutdown hooks (registered via app.Hooks()) always run, even on error. Alternatively set ListenConfig.GracefulContext.
Health checks
Mount the healthcheck middleware for orchestrators (Kubernetes liveness/readiness, load-balancer probes):
import "github.com/gofiber/fiber/v3/middleware/healthcheck"
app.Get("/livez", healthcheck.NewHealthChecker())
app.Get("/readyz", healthcheck.NewHealthChecker(healthcheck.Config{
Probe: func(c fiber.Ctx) bool { return dbIsReachable() },
}))
Observability
- Request logging:
logger.New()(sanitize inputs — see §6). - Request IDs:
requestid.New()adds a correlation ID; read it withc.RequestID(). - Profiling:
pprof.New()exposes Go profiles (internal interface only). - Runtime vars:
expvar.New()forexpvar-format metrics (internal only). - Response time:
responsetime.New()writes handling duration to a header.
Inspecting the running app
app.Stack() returns the full route tree; app.GetRoutes() lists routes (pass true to exclude middleware-registered routes); app.HandlersCount() returns the handler count. These are useful for startup audits and admin endpoints.
Caution
Runtime route mutation —
app.RebuildTree(),app.RemoveRoute(),app.RemoveRouteByName(),app.RemoveRouteFunc()— is not thread-safe and is performance-intensive. Use it only in development, never concurrently with live traffic.
9. Repository Structure (for Contributors)
fiber/
├── app.go App, Config, TrustProxyConfig, lifecycle
├── ctx.go DefaultCtx — the context implementation
├── ctx_interface.go The Ctx interface (+ generated ctx_interface_gen.go)
├── req.go / res.go Request / Response method groups (+ *_interface_gen.go)
├── router.go Route tree, matching, Route struct
├── path.go Route parsing, segments, constraints
├── bind.go Bind entrypoint and BindError
├── group.go Group / sub-router
├── domain.go Hostname-scoped routing
├── listen.go Listen, Listener, ListenConfig, startup banner
├── prefork.go Multi-process serving
├── hooks.go Lifecycle hooks
├── redirect.go Redirect + flash messages (+ msgp codecs)
├── state.go In-process State
├── shared_state.go Storage-backed SharedState (prefork-safe)
├── services.go Service lifecycle management
├── error.go fiber.Error + predefined ErrXxx
├── helpers.go Internal helpers, generic parsers
├── color.go Color scheme
├── constants.go HTTP methods, headers, MIME, status codes
├── binder/ json, xml, form, query, header, cookie, uri, cbor, msgpack binders
├── client/ fasthttp-backed HTTP client (request, response, hooks, cookiejar, transport)
├── extractors/ Token extractors (FromHeader/Form/Query/Param/Chain) — used by csrf/keyauth
├── log/ Pluggable logging facade
├── middleware/ ~30 first-party middleware packages
├── internal/ memory store, storage adapters, redaction, tls test helpers
└── docs/ Docusaurus documentation source (api/, guide/, middleware/)
Extraction note for maintainers/tooling: Fiber is a pure library with no CLI and no HTTP route registry of its own, so AST/regex extraction of "commands", "endpoints", and "config keys" yields essentially nothing (the framework's only os.Getenv read is TERM in the startup banner). The real surfaces are the public method sets of App and Ctx, the Config/ListenConfig structs, the per-middleware Config structs, and the struct tags the binder consumes (json/xml/form/query/header/cookie/uri/msgpack/validate/default). Document from those, not from any extracted table.
Code generation
Several files are generated (*_interface_gen.go, *_msgp.go). The Req/Res interfaces are generated from the Ctx method set; the *_msgp.go files are MessagePack codecs produced by tinylib/msgp for internal structs (redirect data, cache/limiter/idempotency/session entries). Regenerate via the Makefile targets — do not hand-edit generated files.
Contributing workflow
The Makefile exposes the standard quality gates:
make help # list commands
make format # gofumpt / formatting
make lint # golangci-lint (config in .golangci.yml)
make test # full test suite
make coverage # coverage report
make benchmark # benchmarks
make audit # combined quality checks
make tidy # go mod tidy
Run make audit before opening a PR. The repo enforces lint (.golangci.yml), spell-check (.cspell.json), and markdown lint (.markdownlint.yml).
10. Testing Strategy
Fiber apps are tested without binding a socket using app.Test(req *http.Request, config ...TestConfig), which drives the full router/middleware stack against an *http.Request and returns an *http.Response:
func TestRoot(t *testing.T) {
app := fiber.New()
app.Get("/", func(c fiber.Ctx) error { return c.SendString("hello") })
req := httptest.NewRequest("GET", "http://example.com/", nil)
resp, err := app.Test(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != fiber.StatusOK {
t.Fatalf("got %d", resp.StatusCode)
}
}
TestConfig defaults to {Timeout: time.Second, FailOnTimeout: true}. Pass fiber.TestConfig{Timeout: 0} to disable the timeout (for streaming/long handlers).
Warning
app.Test(req)(no config) uses the 1-second default. Passing an emptyfiber.TestConfig{}is not the same — it meansTimeout: 0, FailOnTimeout: false(no timeout at all). Be explicit when overriding.
The framework's own suite mirrors the source layout (*_test.go next to each file), including fuzz tests (helpers_fuzz_test.go), security tests (middleware/cache/cache_security_test.go), and per-middleware tests. Aim for the same: a test file beside each unit, exercising both success and error paths through app.Test.
11. Known Issues & Improvement Areas
These are tracked in the project at this commit and are useful for risk assessment and contribution:
| Area | Issue | Impact |
|---|---|---|
| Cancellation | DefaultCtx.Done() returns nil; Context.Background() used as default in the request path |
context.Context cancellation does not propagate through c — use c.Context()/SetContext. |
| Sessions | No *WithContext session methods; middleware panics on store errors |
A Redis/store outage can crash the request; no way to propagate cancellation into session ops. |
| Security defaults | Session & CSRF cookies default Secure=false, HTTPOnly=false |
Must be hardened (see §6). |
| Logging | No sanitization of user-controlled log values | Log injection risk (see §6). |
| Timeout | Timeout middleware can leak Ctx on timeout |
Potential unbounded memory growth under timeout-heavy load. |
| Goroutines | Background goroutines without shutdown hooks | Leaks on shutdown for certain features. |
| Proxy | X-Forwarded-For trusted-proxy IP stripping |
Edge cases in proxy chain parsing. |
| Concurrency | Global mutex contention in storage-backed middleware (limiter/cache/session) |
Throughput ceiling at high RPS; sharding proposed. |
| Binder | Per-request map allocations | Allocation pressure; pooling proposed. |
Improvement directions the maintainers are pursuing: sharding the memory store and idempotency locker to reduce lock contention, narrowing client hook lock scope, unifying internal and custom route constraints behind one interface, and reducing binder allocations.
12. Quick Reference
Create & serve
app := fiber.New(fiber.Config{ /* ... */ })
app.Listen(":3000")
app.Listen(":443", fiber.ListenConfig{CertFile: "c.pem", CertKeyFile: "k.pem"})
app.Listen(":8080", fiber.ListenConfig{EnablePrefork: true})
app.ShutdownWithTimeout(10 * time.Second)
Routing
app.Get/Post/Put/Patch/Delete/Head/Options(path, handler)
app.All(path, handler) app.Add([]string{...}, path, handler)
app.Group(prefix, mw...) app.Route(prefix, fn, name...)
app.RouteChain(path).Get(h).Post(h) app.Domain(host).Get(path, h)
app.Use(mw) app.Use(prefix, mw) app.Use(prefix, subApp) // mount
Context (selected)
c.Params/Query/Get/Cookies(key) c.Body()/BodyRaw() c.IP()/IPs()
c.Bind().Body/JSON/Query/URI/Header/Cookie/All(&v)
c.JSON/XML/CBOR/MsgPack(v) c.SendString/Send/SendFile/Download/Render
c.Status(code).SendString(...) c.SendStatus(code) c.Set(k,v) c.Cookie(&Cookie{})
c.Next() c.Locals(k, v) c.Context() c.RequestCtx() c.Redirect().To(path)
Introspection / lifecycle
app.Stack() app.GetRoutes(true) app.HandlersCount() app.Config()
app.Server() app.Handler() app.Hooks() app.State() app.SharedState()
fiber.NewError(code, msg) fiber.IsChild() app.Test(req, cfg...)
Must-have production middleware
app.Use(recover.New())
app.Use(logger.New())
app.Use(cors.New(cors.Config{AllowOrigins: []string{"https://you.example"}}))
app.Use(limiter.New(limiter.Config{Max: 100, Expiration: time.Minute}))
// + TrustProxy config, hardened session/csrf cookies, healthcheck probes