# Difference Between Gin's New() and Default() Functions

> Understand the key differences between Gin's New() and Default() functions. Learn when to use each for efficient web framework setup.

- Repository: [Gin-Gonic/gin](https://github.com/gin-gonic/gin)
- Tags: internals
- Published: 2026-02-27

---

**`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`](https://github.com/gin-gonic/gin/blob/main/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`](https://github.com/gin-gonic/gin/blob/main/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 in [`logger.go`](https://github.com/gin-gonic/gin/blob/main/logger.go))
- **`Recovery()`**: Catches panics during request handling and returns HTTP 500 errors (defined in [`recovery.go`](https://github.com/gin-gonic/gin/blob/main/recovery.go))

## Source Code Implementation

According to the `gin-gonic/gin` source code, the implementation difference is minimal but significant:

In [`gin.go`](https://github.com/gin-gonic/gin/blob/main/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:

```go
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.

```go
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.

```go
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 `*Engine` with no middleware, defined in [`gin.go`](https://github.com/gin-gonic/gin/blob/main/gin.go) lines 202-233.
- **`gin.Default()`** wraps `New()` and automatically attaches `Logger()` and `Recovery()` middleware, defined in [`gin.go`](https://github.com/gin-gonic/gin/blob/main/gin.go) lines 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`](https://github.com/gin-gonic/gin/blob/main/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()`.