> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lightning-go.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# App Config

> Configure a Lightning application using the Config struct and constructor functions.

Lightning gives you two ways to create an application: `NewApp()` for full control over configuration, and `DefaultApp()` as a batteries-included shortcut. Both accept the same `Config` struct.

## Config fields

<ParamField path="AppName" type="string" default="lightning-app">
  The name shown as a prefix in all log output produced by the application's built-in logger.
</ParamField>

<ParamField path="JSONEncoder" type="JSONMarshal">
  A custom JSON marshaling function with the signature `func(v any) ([]byte, error)`. When omitted, Lightning uses `encoding/json.Marshal`.
</ParamField>

<ParamField path="JSONDecoder" type="JSONUnmarshal">
  A custom JSON unmarshaling function with the signature `func(data []byte, v any) error`. When omitted, Lightning uses `encoding/json.Unmarshal`.
</ParamField>

<ParamField path="NotFoundHandler" type="HandlerFunc">
  A handler invoked when no route matches the incoming request. The default handler responds with `404 Not Found` as plain text.
</ParamField>

<ParamField path="EnableDebug" type="bool" default="false">
  When `true`, Lightning registers a `GET /__debug__/router_map` endpoint that returns all registered routes as JSON. Useful for verifying route registration during development.
</ParamField>

<ParamField path="MaxRequestBodySize" type="int64" default="0">
  The maximum number of bytes the server reads from a request body. A value of `0` means unlimited. Requests that exceed this limit are rejected by the underlying fasthttp server.
</ParamField>

## NewApp()

`NewApp` accepts zero or one `*Config` argument. Any field you leave at its zero value falls back to the Lightning default for that field.

### No configuration (all defaults)

```go theme={null}
package main

import "github.com/go-labx/lightning"

func main() {
    app := lightning.NewApp()

    app.Get("/ping", func(ctx *lightning.Context) {
        ctx.Text(lightning.StatusOK, "pong")
    })

    app.Run(":8080")
}
```

### Custom configuration

```go theme={null}
package main

import "github.com/go-labx/lightning"

func main() {
    app := lightning.NewApp(&lightning.Config{
        AppName:            "payments-api",
        EnableDebug:        true,
        MaxRequestBodySize: 4 * 1024 * 1024, // 4 MB
        NotFoundHandler: func(ctx *lightning.Context) {
            ctx.JSON(lightning.StatusNotFound, lightning.Map{
                "error": "route not found",
                "path":  ctx.Path,
            })
        },
    })

    app.Get("/ping", func(ctx *lightning.Context) {
        ctx.Text(lightning.StatusOK, "pong")
    })

    app.Run(":8080")
}
```

<Note>
  You only need to set the fields you want to override. `NewApp` merges your `Config` on top of the defaults, so unset fields keep their default values.
</Note>

## DefaultApp()

`DefaultApp` is equivalent to calling `NewApp()` and then registering both the `Logger` and `Recovery` middleware:

```go theme={null}
func DefaultApp() *Application {
    app := NewApp()
    app.Use(Logger())
    app.Use(Recovery())
    return app
}
```

Use `DefaultApp` when you want structured request logging and panic recovery without any extra setup:

```go theme={null}
package main

import "github.com/go-labx/lightning"

func main() {
    app := lightning.DefaultApp()

    app.Get("/ping", func(ctx *lightning.Context) {
        ctx.Text(lightning.StatusOK, "pong")
    })

    app.Run(":8080")
}
```

## Complete example

The following example shows a fully configured application with a custom JSON encoder, a branded 404 response, debug mode, and a 2 MB body size limit.

```go theme={null}
package main

import (
    "encoding/json"

    "github.com/go-labx/lightning"
)

func main() {
    app := lightning.NewApp(&lightning.Config{
        AppName:            "inventory-service",
        EnableDebug:        true,
        MaxRequestBodySize: 2 * 1024 * 1024, // 2 MB
        JSONEncoder: func(v any) ([]byte, error) {
            return json.Marshal(v)
        },
        JSONDecoder: func(data []byte, v any) error {
            return json.Unmarshal(data, v)
        },
        NotFoundHandler: func(ctx *lightning.Context) {
            ctx.JSON(lightning.StatusNotFound, lightning.Map{
                "service": "inventory-service",
                "error":   "endpoint not found",
            })
        },
    })

    // Register middleware
    app.Use(lightning.Logger())
    app.Use(lightning.Recovery())

    // Routes
    app.Get("/items", func(ctx *lightning.Context) {
        ctx.JSON(lightning.StatusOK, lightning.Map{"items": []string{}})
    })

    app.Run(":8080")
}
```
