modkit

A Go framework for building modular backend services, inspired by NestJS.
modkit brings NestJS-style module organization to Go—without reflection, decorators, or magic. Define modules with explicit imports, providers, controllers, and exports. The kernel builds a dependency graph, enforces visibility, and bootstraps your app deterministically.
Why modkit?
modkit is a Go-idiomatic alternative to decorator-driven frameworks. It keeps wiring explicit, avoids reflection, and makes module boundaries and dependencies visible in code.
| If you want... |
modkit gives you... |
| NestJS-style modules in Go |
imports, providers, controllers, exports |
| Explicit dependency injection |
String tokens + resolver, no reflection |
| Debuggable bootstrap |
Deterministic graph construction with clear errors |
| Minimal framework overhead |
Thin HTTP adapter on chi, no ORM, no config magic |
Compared to Other Go Frameworks
| If you use... |
modkit is different because... |
| google/wire |
modkit adds module boundaries + visibility enforcement |
| uber-go/fx |
No reflection, explicit Build functions |
| samber/do |
Full module system with imports/exports |
| No framework |
Structured module organization without boilerplate |
See the full comparison for details.
Quick Example
// Define a module
type UsersModule struct{}
func (m *UsersModule) Definition() module.ModuleDef {
return module.ModuleDef{
Name: "users",
Providers: []module.ProviderDef{{
Token: "users.service",
Build: func(r module.Resolver) (any, error) {
return NewUsersService(), nil
},
}},
Controllers: []module.ControllerDef{{
Name: "UsersController",
Build: func(r module.Resolver) (any, error) {
svc, err := module.Get[UsersService](r, "users.service")
if err != nil {
return nil, err
}
return NewUsersController(svc), nil
},
}},
Exports: []module.Token{"users.service"},
}
}
// Bootstrap and serve
func main() {
app, err := kernel.Bootstrap(&UsersModule{})
if err != nil {
log.Fatal(err)
}
router := mkhttp.NewRouter()
mkhttp.RegisterRoutes(mkhttp.AsRouter(router), app.Controllers)
mkhttp.Serve(":8080", router)
}
Installation
Library
go get github.com/go-modkit/modkit
Install the modkit CLI using go install:
go install github.com/go-modkit/modkit/cmd/modkit@latest
Or download a pre-built binary from the releases page.
Requires Go 1.25.7+
We pin the patch level to 1.25.7 in CI to align with vulnerability scanning and keep a consistent security posture.
Quick Start with CLI
Scaffold a new modkit application in seconds:
# Create a new app
modkit new app myapp
cd myapp
# Run the application
go run cmd/api/main.go
Add providers and controllers to existing modules:
# Create a new module
cd internal/modules
mkdir users
cd users
# Initialize module.go with basic structure
cat > module.go << 'EOF'
package users
import "github.com/go-modkit/modkit/modkit/module"
type UsersModule struct{}
func (m *UsersModule) Definition() module.ModuleDef {
return module.ModuleDef{
Name: "users",
Providers: []module.ProviderDef{},
Controllers: []module.ControllerDef{},
}
}
EOF
# Add a provider
modkit new provider service
# Add a controller
modkit new controller users
The CLI automatically registers providers and controllers in your module's Definition() function.
Features
- Module System — Compose apps from self-contained modules with explicit boundaries
- Dependency Injection — Providers built on first access, cached as singletons
- Visibility Enforcement — Only exported tokens are accessible to importers
- HTTP Adapter — Chi-based router with explicit route registration
- No Reflection — Everything is explicit and type-safe
- Deterministic Bootstrap — Predictable initialization order with clear error messages
Feature Matrix
Packages
| Package |
Description |
modkit/module |
Module metadata types (ModuleDef, ProviderDef, Token) |
modkit/config |
Typed environment config module helpers |
modkit/kernel |
Graph builder, visibility enforcer, bootstrap |
modkit/http |
HTTP adapter for chi router |
modkit/logging |
Logging interface with slog adapter |
Architecture
flowchart LR
subgraph Input
A[📦 Module Definitions]
end
subgraph Kernel
B[🔗 Graph Builder]
C[📦 Container]
end
subgraph Output
D[🎮 Controllers]
E[🌐 HTTP Adapter]
end
A --> B
B --> C
C --> D
D --> E
style A fill:#e1f5fe,stroke:#01579b,color:#01579b
style B fill:#fff3e0,stroke:#e65100,color:#e65100
style C fill:#fff3e0,stroke:#e65100,color:#e65100
style D fill:#e8f5e9,stroke:#2e7d32,color:#2e7d32
style E fill:#e8f5e9,stroke:#2e7d32,color:#2e7d32
See Architecture Guide for details.
Documentation
Guides:
Reference:
Examples:
How It Compares to NestJS
| Concept |
NestJS |
modkit |
| Module definition |
@Module() decorator |
ModuleDef struct |
| Dependency injection |
Constructor injection via metadata |
Explicit module.Get[T](r, token) |
| Route binding |
@Get(), @Post() decorators |
RegisterRoutes(router) method |
| Middleware |
NestMiddleware interface |
func(http.Handler) http.Handler |
| Guards/Pipes/Interceptors |
Framework abstractions |
Standard Go middleware |
Status
modkit is in early development. APIs may change before v0.1.0.
After v0.1.0, changes will follow semantic versioning.
Questions? Start a Discussion.
Contributing
See CONTRIBUTING.md. We welcome issues, discussions, and PRs.
License
MIT — see LICENSE