# Configuration

> Customize and extend Nitro defaults.

<read-more>

See [config reference](/config) for available options.
</read-more>

## Config file

You can customize your Nitro builder with a configuration file.

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  // Nitro options
})
```

```ts [vite.config.ts]
import { defineConfig } from 'vite'
import { nitro } from 'nitro/vite'

export default defineConfig({
  plugins: [
    nitro()
  ],
  nitro: {
    // Nitro options
  }
})

```

> [!TIP]
> Nitro loads the configuration using [c12](https://github.com/unjs/c12), giving more  possibilities such as using `.nitrorc` file in current working directory or in the user's home directory.

### Environment-specific config

Using [c12](https://github.com/unjs/c12) conventions, you can provide environment-specific overrides using `$development` and `$production` keys:

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  logLevel: 3,
  $development: {
    // Options applied only in development mode
    debug: true,
  },
  $production: {
    // Options applied only in production builds
    minify: true,
  },
})
```

The environment name is `"development"` during `nitro dev` and `"production"` during `nitro build`.

### Extending configs

You can extend from other configs or presets using the `extends` key:

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  extends: "./base.config",
})
```

### Config from `package.json`

You can also provide Nitro configuration under the `nitro` key in your `package.json` file.

## Directory options

Nitro provides several options for controlling directory structure:

| Option | Default | Description |
| --- | --- | --- |
| `rootDir` | `.` (current directory) | The root directory of the project. |
| `serverDir` | `false` | Server source directory (set to `"server"` or `"./"` to enable). |
| `buildDir` | `node_modules/.nitro` | Directory for build artifacts. |
| `output.dir` | `.output` | Production output directory. |
| `output.serverDir` | `.output/server` | Server output directory. |
| `output.publicDir` | `.output/public` | Public assets output directory. |

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  serverDir: "server",
  buildDir: "node_modules/.nitro",
  output: {
    dir: ".output",
  },
})
```

> [!NOTE]
> The `srcDir` option is deprecated. Use `serverDir` instead.

## Environment variables

Certain Nitro behaviors can be configured using environment variables:

| Variable | Description |
| --- | --- |
| `NITRO_PRESET` | Override the deployment preset. |
| `NITRO_COMPATIBILITY_DATE` | Set the compatibility date. |
| `NITRO_APP_BASE_URL` | Override the base URL (default: `/`). |

## Runtime configuration

Nitro provides a runtime config API to expose configuration within your application, with the ability to update it at runtime by setting environment variables. This is useful when you want to expose different configuration values for different environments (e.g. development, staging, production). For example, you can use this to expose different API endpoints for different environments or to expose different feature flags.

First, you need to define the runtime config in your configuration file.

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  runtimeConfig: {
    apiToken: "dev_token", // `dev_token` is the default value
  }
});
```

You can now access the runtime config using `useRuntimeConfig()`.

```ts [api/example.get.ts]
import { defineHandler } from "nitro";
import { useRuntimeConfig } from "nitro/runtime-config";

export default defineHandler((event) => {
  return useRuntimeConfig().apiToken; // Returns `dev_token`
});
```

### Nested objects

Runtime config supports nested objects. Keys at any depth are mapped to environment variables using the `NITRO_` prefix and `UPPER_SNAKE_CASE` conversion:

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  runtimeConfig: {
    database: {
      host: "localhost",
      port: 5432,
    },
  },
});
```

```bash [.env]
NITRO_DATABASE_HOST="db.example.com"
NITRO_DATABASE_PORT="5433"
```

> [!NOTE]
> Only keys defined in `runtimeConfig` in your config file will be considered. You cannot introduce new keys using environment variables alone.

### Serialization

Runtime config values must be serializable (strings, numbers, booleans, plain objects, and arrays). Non-serializable values (class instances, functions, etc.) will trigger a warning at build time.

Values that are `undefined` or `null` in the config are replaced with empty strings (`""`) as a fallback.

### Local development

You can update the runtime config using environment variables. You can use a `.env` or `.env.local` file in development and use platform variables in production (see below).

Create an `.env` file in your project root:

```bash [.env]
NITRO_API_TOKEN="123"
```

Re-start the development server, fetch the `/api/example` endpoint and you should see `123` as the response instead of `dev_token`.

> [!NOTE]
> The `.env` and `.env.local` files are only loaded during development (`nitro dev`). In production, use your platform's native environment variable mechanism.

Do not forget that you can still universally access environment variables using `import.meta.env` or `process.env` but avoid using them in ambient global contexts to prevent unexpected behavior.

### Production

You can define variables in your production environment to update the runtime config.

<warning>

All variables must be prefixed with `NITRO_` to be applied to the runtime config. They will override the runtime config variables defined within your `nitro.config.ts` file.
</warning>

```bash [.env]
NITRO_API_TOKEN="123"
```

In runtime config, define key using camelCase. In environment variables, define key using snake_case and uppercase.

```ts
{
  helloWorld: "foo"
}
```

```bash
NITRO_HELLO_WORLD="foo"
```

### Custom env prefix

You can configure a secondary environment variable prefix using the `nitro.envPrefix` runtime config key. This prefix is checked in addition to the default `NITRO_` prefix:

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  runtimeConfig: {
    nitro: {
      envPrefix: "APP_",
    },
    apiToken: "",
  },
});
```

With this configuration, both `NITRO_API_TOKEN` and `APP_API_TOKEN` will be checked as overrides.

### Env expansion

When enabled, environment variable references using `{{VAR_NAME}}` syntax in runtime config string values are expanded at runtime:

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  experimental: {
    envExpansion: true,
  },
  runtimeConfig: {
    url: "https://{{APP_DOMAIN}}/api",
  },
});
```

```bash
APP_DOMAIN="example.com"
```

At runtime, `useRuntimeConfig().url` will resolve to `"https://example.com/api"`.
