Difference Between Gin's New() and Default() Functions
gin.Default() automatically registers the Logger and Recovery middleware, while gin.New() returns a blank engine with no middleware attached.
The gin-gonic/gin framework offers two primary constructors for initializing the core router, and understanding the difference between Gin's New() and Default() functions is critical for controlling your application's middleware chain. Both functions return a pointer to an Engine struct configured with identical default router settings, but they differ fundamentally in their initial middleware composition.
Core Distinctions
The functional distinction lies entirely in the middleware stack attached at initialization. All other router behaviors—including trailing slash redirects, client IP forwarding, and option handling—remain identical between the two constructors.
gin.New(): Blank Engine Initialization
Defined in gin.go at lines 202-233, the New() function instantiates a bare Engine struct with default internal configurations but no global middleware. This provides complete control over the middleware pipeline, requiring explicit registration of any handlers via engine.Use().
gin.Default(): Pre-configured Engine
Located in gin.go at lines 35-41, Default() is a convenience wrapper that internally calls New() and immediately attaches two essential middlewares:
Logger(): Logs incoming HTTP requests to the console (defined inlogger.go)Recovery(): Catches panics during request handling and returns HTTP 500 errors (defined inrecovery.go)
Source Code Implementation
According to the gin-gonic/gin source code, the implementation difference is minimal but significant:
In gin.go (lines 202-233), New() initializes the Engine struct with default boolean flags like RedirectTrailingSlash and ForwardedByClientIP, allocates internal maps for route trees, and returns the instance. No middleware functions are appended to the RouterGroup.handlers slice.
Conversely, Default() (lines 35-41) executes the following sequence:
func Default(opts ...OptionFunc) *Engine {
engine := New()
engine.Use(Logger(), Recovery())
return engine.With(opts...)
}
This single line difference—engine.Use(Logger(), Recovery())—constitutes the entire functional distinction between the two constructors.
Practical Usage Examples
Custom Middleware Stack with gin.New()
Use gin.New() when you need full control over middleware, such as implementing custom logging, authentication, or omitting recovery handling for specialized testing scenarios.
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func CustomAuth() gin.HandlerFunc {
return func(c *gin.Context) {
// Authentication logic
c.Next()
}
}
func main() {
// Initialize blank engine
r := gin.New()
// Add only required middleware
r.Use(CustomAuth())
// Explicitly add logging only if needed
// r.Use(gin.Logger())
r.GET("/api", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"status": "active"})
})
r.Run(":8080")
}
In this configuration, the engine processes requests without automatic logging or panic recovery unless explicitly added.
Quick Start with gin.Default()
Use gin.Default() for standard web services requiring immediate request logging and panic protection without additional configuration.
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
// Initialize with Logger and Recovery
r := gin.Default()
r.GET("/health", func(c *gin.Context) {
c.String(http.StatusOK, "ok")
})
r.Run(":8080")
}
This setup automatically prints request details to stdout and recovers from panics to prevent server crashes.
When to Use Each Approach
Choose your initialization method based on middleware requirements:
-
Use
gin.New()when building APIs with custom logging formats, specialized metrics collection, or when you need to exclude the Recovery middleware for specific testing environments. -
Use
gin.Default()for rapid prototyping, internal tools, or standard REST services where console logging and panic recovery are acceptable defaults.
Both constructors support variadic OptionFunc parameters for additional configuration, and both return a fully functional *Engine ready for route registration.
Summary
gin.New()returns a blank*Enginewith no middleware, defined ingin.golines 202-233.gin.Default()wrapsNew()and automatically attachesLogger()andRecovery()middleware, defined ingin.golines 35-41.- Both functions create identical router configurations regarding trailing slash handling, IP forwarding, and route tree initialization.
- The choice depends solely on whether you need the default logging and panic recovery middleware.
Frequently Asked Questions
Can I add Logger and Recovery to an engine created with gin.New()?
Yes. You can manually attach the default middleware at any time by calling engine.Use(gin.Logger(), gin.Recovery()). This produces functionality identical to gin.Default() while allowing you to insert custom middleware between the logger and recovery handlers.
Does gin.Default() impact performance compared to gin.New()?
The performance impact is negligible for most applications. The Logger middleware adds minimal overhead for I/O operations, while Recovery adds a deferred function call to catch panics. If optimizing for maximum throughput in high-frequency microservices, gin.New() allows you to omit these defaults.
What happens if I use Recovery middleware in production?
The Recovery middleware prevents individual requests from crashing your entire server by catching panics, logging the stack trace, and returning HTTP 500. According to recovery.go, this is essential for production stability, though you may want to pair it with custom error reporting rather than relying solely on console output.
Is it possible to remove middleware from a gin.Default() instance?
No, Gin does not provide a mechanism to remove middleware once registered. If you need an engine without Logger or Recovery, you must use gin.New() instead of gin.Default().
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →