Preface: Why Build Yet Another Go Framework
In todayβs highly mature Go ecosystem, βbuilding yet another Go web frameworkβ may seem redundantβor even boring.
We already have:
- Feature-rich, full-stack frameworks with massive communities
- Performance-oriented, low-level HTTP / RPC frameworks
- Cloud-native application runtimes deeply integrated with Kubernetes
- Complete engineering systems tailored for microservices
Plumego is not meant to compete with them.
The motivation behind Plumego comes from a different, often overlooked, set of real-world engineering needs:
Can we still build a long-lived, fully predictable, and elegant service framework using almost nothing but the Go standard library?
Plumego does not aim to have βthe most features.β Instead, its goals are:
- Code that can be fully read and understood
- Behavior that can be completely reasoned about
- Architecture that evolves naturally
- A foundation that will not become technical debt even ten years later
If you are looking for the last Go service skeleton you are willing to maintain long-term, Plumego may be exactly what you need.
What Is Plumego
Plumego is a minimal service framework built on the Go standard library.
It does not try to do everything for you. Instead, it provides a stable, restrained, and engineering-oriented minimal capability set to help you:
- Quickly bootstrap a runnable HTTP service
- Clearly organize routing, context, and middleware
- Build extensible business structures without heavy dependencies
- Reserve clear boundaries for future capabilities such as WebSocket, Webhooks, Pub-Sub, JWT, and Local DB
Plumegoβs core philosophy can be summarized in one sentence:
βUse the least magic in exchange for the greatest certainty.β
Design Philosophy: The Five Principles Plumego Stands By
1. Standard Library First
Plumego is built almost entirely on the Go standard library:
net/httpcontextencoding/jsonsynctime
This means:
- No hidden behavior
- No hard-to-upgrade third-party core dependencies
- No being held hostage by external design decisions
What you see is simply Go itself.
2. Clear Structure Over Feature Accumulation
Plumego does not aim for βone line does everything.β
Instead, it cares deeply about:
- Where requests come from
- When middleware is executed
- How context is constructed and passed
- Where handlers begin and end their responsibilities
Every step is explicit, traceable, and debuggable.
3. Predictable Behavior Over Developer βConvenienceβ
Many frameworks provide strong early-stage convenience:
- Automatic injection
- Implicit binding
- Global magic
- Extreme βconvention over configurationβ
Plumego, however, focuses on harder questions:
- Will you still dare to modify it a year later?
- Can a new teammate take over in three years?
- Can you locate issues quickly when production breaks?
For this reason, Plumego remains highly cautious about implicit behavior.
4. A Framework as a Skeleton, Not a Product
Plumego itself is not a βfinished product.β
It is closer to:
- A prunable engineering skeleton
- A recommended but non-mandatory organizational approach
- A starting point that can be copied across repositories
You can build on Plumego to create:
- Internal services
- Small SaaS products
- API gateways
- Game backends
- Automation systems
- Tool-oriented services
5. Designed for Long-Term Evolution
Plumego is designed with long-term evolution in mind:
- Module replacement
- Capability layering
- Service decomposition
- Monolith β multi-service transitions
It does not force you into microservices on day one, nor does it block that path in the future.
High-Level Architecture Overview
At a macro level, a Plumego-based service typically consists of the following layers:
ββββββββββββββββββββββββββββ
β HTTP Server β
β (net/http standard) β
ββββββββββββ¬βββββββββββββββ
β
ββββββββββββΌβββββββββββββββ
β Router β
β Route matching & dispatchβ
ββββββββββββ¬βββββββββββββββ
β
ββββββββββββΌβββββββββββββββ
β Middleware β
β Cross-cutting concerns β
ββββββββββββ¬βββββββββββββββ
β
ββββββββββββΌβββββββββββββββ
β Context β
β Request context wrapperβ
ββββββββββββ¬βββββββββββββββ
β
ββββββββββββΌβββββββββββββββ
β Handler β
β Business entry point β
ββββββββββββ¬βββββββββββββββ
β
ββββββββββββΌβββββββββββββββ
β Domain / Usecase β
β Pure business logic β
ββββββββββββββββββββββββββββ
Plumego strictly separates:
- Framework layer: responsible only for the request lifecycle
- Business layer: unaware of HTTP and independent of the framework
HTTP Server: Returning to the Purity of net/http
Plumego does not reimplement an HTTP server.
It directly uses Goβs standard http.Server, while providing:
- Clear startup and shutdown flows
- Controllable timeout configurations
- Explicit context lifecycle management
This allows you to:
- Integrate standard reverse proxies (Nginx / Caddy)
- Use existing monitoring and tracing solutions
- Perform precise behavioral tuning
Router: Clarity Over Fancy DSLs
Plumegoβs router design follows three principles:
- Routing rules must be readable at a glance
- Matching order must be predictable
- Path parsing details must not be hidden
Rather than complex DSLs, Plumego prefers clarity:
router.GET("/users/:id", handler)
router.POST("/users", handler)
You know exactly how it worksβand can easily replace it if needed.
Middleware: Explicit, Linear, and Composable
In Plumego, middleware is not a black box.
It follows a strict execution order:
Request
β Middleware A
β Middleware B
β Handler
β Middleware B
β Middleware A
Response
Typical middleware includes:
- Logging
- TraceID injection
- Authentication
- Rate limiting
- Panic recovery
Each middleware is just an ordinary Go function.
Context: Friendlier Than net/http, Not More Complex
Plumego wraps the standard context.Context with a more business-friendly context that includes:
- Request information
- Response writing helpers
- Common utility methods
- Unified error handling
But it does not:
- Hide the original context
- Force global variables
- Introduce obscure lifecycle rules
Handler: A Clear System Boundary
In Plumegoβs philosophy, handlers are:
The boundary of the system, not the center of the business.
A handler has only three responsibilities:
- Parse input
- Invoke business logic
- Construct output
True business rules should live in:
- Domain
- Usecase
- Service
This ensures your business code is:
- Testable
- Reusable
- Runnable independently of HTTP
Why Plumego Is Especially Suitable for Long-Term Projects
Plumego is a strong fit if any of the following apply to you:
- You do not want to be locked into a framework
- You value code longevity over short-term velocity
- You are building a system meant to run for many years
- You need a skeleton that can be copied, trimmed, and evolved
- You are tired of frameworks with too much magic
Plumego does not try to please everyone.
It exists solely for engineers willing to trade a bit of explicit code for long-term certainty.
The Relationship Between Plumego and Birdor
Plumego is one of the foundational service skeletons in the Birdor engineering system.
Within Birdorβs design philosophy:
- The frontend emphasizes semantics and long-term consistency
- Tools emphasize local-first and non-intrusive design
- The backend equally pursues calmness, restraint, and reasonability
Plumego is the natural backend extension of this philosophy.
Conclusion: The True Value of Plumego
The value of Plumego is not in what it can do.
It lies in:
- What it explicitly refuses to do
- Which temptations it resists
- How much space it leaves for the future
If you are looking for:
A Go service framework you will not personally tear down three years from now.
Then Plumego deserves a serious look.
Plumego is not about speed. It is about trust.