# Difference Between JSON, SecureJSON, PureJSON, and IndentedJSON in Gin

> Understand the differences between JSON, SecureJSON, PureJSON, and IndentedJSON in Gin. Learn about HTML escaping, pretty-printing, security against hijacking, and unescaped streaming for efficient JSON rendering.

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

---

**TLDR:** Gin provides four JSON renderers in its `render` package: `JSON` for standard serialization with HTML escaping enabled; `IndentedJSON` for human-readable, pretty-printed output; `SecureJSON` to prevent JSON array hijacking attacks via prefix injection; and `PureJSON` for unescaped, streaming encoding that bypasses HTML entity translation. All implement the `render.Renderer` interface but differ in security controls, formatting, and memory allocation strategies.

The Gin web framework offers multiple ways to serialize JSON responses depending on your security, readability, and performance requirements. Understanding the **difference between JSON, SecureJSON, PureJSON, and IndentedJSON in Gin** allows you to select the optimal renderer for your API endpoints. These four concrete types reside in `github.com/gin-gonic/gin/render` and implement the `render.Renderer` interface, each manipulating the JSON payload differently before writing to the `http.ResponseWriter`.

## Standard JSON Rendering

The `JSON` type provides the default serialization behavior used by `c.JSON()`. In [`render/json.go`](https://github.com/gin-gonic/gin/blob/main/render/json.go) at lines 56-60, the `Render` method calls `WriteJSON`, which marshals the value using `json.API.Marshal` and writes the bytes directly to the response writer.

This renderer enables **HTML escaping** by default, translating characters like `<`, `>`, and `&` into their Unicode escape sequences (`\u003c`, `\u003e`, `\u0026`). It sets the content-type header to `application/json; charset=utf-8` and produces compact, single-line output without indentation.

```go
c.JSON(http.StatusOK, gin.H{
    "msg":   "hello",
    "count": 5,
    "html":  "<script>test</script>", // Escaped to \u003cscript\u003e
})

```

## Pretty-Printed Responses with IndentedJSON

Use `IndentedJSON` when you need human-readable output for debugging or development APIs. According to the source in [`render/json.go`](https://github.com/gin-gonic/gin/blob/main/render/json.go) at lines 77-85, this renderer invokes `json.API.MarshalIndent` with a four-space prefix and indent string.

The content-type header remains identical to standard JSON (`application/json; charset=utf-8`), but the response body includes newline characters and indentation for nested structures. This convenience trades payload size and slight performance for improved readability.

```go
c.IndentedJSON(http.StatusOK, gin.H{
    "users": []string{"alice", "bob"},
    "meta":  map[string]int{"total": 2},
})

```

## Security-Hardened JSON with SecureJSON

The `SecureJSON` renderer mitigates **JSON hijacking** attacks where malicious sites load sensitive JSON arrays via `<script>` tags. As implemented in [`render/json.go`](https://github.com/gin-gonic/gin/blob/main/render/json.go) at lines 93-109, this renderer checks if the marshaled data starts with `[` and ends with `]` using `bytes.HasPrefix` and `bytes.HasSuffix`.

If the top-level value is an array, `SecureJSON` writes the configured prefix—defaulting to `")]}',\n"` via `JSONSecurePrefix`—before the JSON bytes. This prefix invalidates the JavaScript array literal syntax, preventing unauthorized access while remaining valid JSON for compliant parsers.

```go
// Protects against hijacking when returning arrays
c.SecureJSON(http.StatusOK, []string{"secret1", "secret2"})

```

## Unescaped Streaming with PureJSON

`PureJSON` disables HTML escaping and streams encoding directly to the client, reducing memory overhead for large payloads. The implementation in [`render/json.go`](https://github.com/gin-gonic/gin/blob/main/render/json.go) at lines 83-89 creates a new encoder via `json.API.NewEncoder(w)`, calls `SetEscapeHTML(false)`, and streams the output without buffering an intermediate byte slice.

Use this renderer when your payload contains pre-sanitized HTML or when you need to avoid the default escaping overhead. Be cautious: disabling escaping can expose XSS vulnerabilities if the data contains untrusted user input.

```go
// Skips HTML escaping, outputs raw <script> tags
c.PureJSON(http.StatusOK, map[string]interface{}{
    "html": "<script>alert('xss');</script>",
})

```

## Summary

- **JSON**: The default renderer at `render/json.go:56-60` that balances speed and safety with HTML escaping and compact output.
- **IndentedJSON**: Pretty-prints with four-space indentation via `MarshalIndent` at `render/json.go:77-85`, ideal for development.
- **SecureJSON**: Injects the `")]}',\n"` prefix before top-level arrays at `render/json.go:93-109` to prevent JSON hijacking.
- **PureJSON**: Streams unescaped JSON directly to `http.ResponseWriter` at `render/json.go:83-89`, optimizing for performance and HTML fidelity.

## Frequently Asked Questions

### What is the main difference between JSON and PureJSON in Gin?

Standard `JSON` marshals to an intermediate byte slice with HTML escaping enabled, protecting against XSS but adding overhead. `PureJSON` streams directly to the response writer via `json.API.NewEncoder` with `SetEscapeHTML(false)`, eliminating buffering and preserving raw HTML characters like `<` and `>`.

### When should I use SecureJSON instead of regular JSON?

Use `SecureJSON` when your endpoint returns JSON arrays as the top-level element and the data contains sensitive information. According to the `gin-gonic/gin` source code, it prefixes array responses with `")]}',\n"` to prevent JSON hijacking attacks where third-party sites could steal array data via script tags.

### Does IndentedJSON affect performance compared to standard JSON?

Yes. `IndentedJSON` calls `MarshalIndent` rather than `Marshal`, producing larger payloads due to whitespace and requiring additional formatting CPU cycles. The implementation in [`render/json.go`](https://github.com/gin-gonic/gin/blob/main/render/json.go) uses four-space indentation, significantly increasing response size for large nested objects compared to the compact `JSON` renderer.

### Can I configure the indentation width for IndentedJSON?

No. The indentation is hardcoded to four spaces in [`render/json.go`](https://github.com/gin-gonic/gin/blob/main/render/json.go) at lines 77-85. If you require custom indentation or alternative formatting, you must marshal the JSON manually using `json.MarshalIndent` with your preferred parameters and write it using `c.Data` or `c.String`.