Configuration
Customize and extend Nitro defaults.
#Config file
You can customize your Nitro builder with a configuration file.
import { defineConfig } from "nitro";
export default defineConfig({
// Nitro options
})#Supported configuration files
Nitro loads its configuration using c12 from the project root directory (the directory passed to the nitro CLI, defaulting to the current working directory). The following locations are checked in order and the first matching file is used:
nitro.config.{js,ts,mjs,cjs,mts,cts,json,jsonc,json5,yaml,yml,toml}.config/nitro.{js,ts,mjs,cjs,mts,cts,json,jsonc,json5,yaml,yml,toml}.config/nitro.config.{js,ts,mjs,cjs,mts,cts,json,jsonc,json5,yaml,yml,toml}
Using nitro.config.ts is the recommended convention.
An extensionless .nitrorc file in the same directory is also loaded (using key=value syntax) and merged with lower priority than the main configuration file.
When using the Vite plugin, options can also be passed inline with the nitro key in vite.config.ts (as shown above).
#Environment-specific config
Using c12 conventions, you can provide environment-specific overrides using $development and $production keys:
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:
import { defineConfig } from "nitro";
export default defineConfig({
extends: "./base.config",
})#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. |
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.
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().
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:
import { defineConfig } from "nitro";
export default defineConfig({
runtimeConfig: {
database: {
host: "localhost",
port: 5432,
},
},
});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:
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.
NITRO_API_TOKEN="123"In runtime config, define key using camelCase. In environment variables, define key using snake_case and uppercase.
{
helloWorld: "foo"
}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:
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:
import { defineConfig } from "nitro";
export default defineConfig({
experimental: {
envExpansion: true,
},
runtimeConfig: {
url: "https://{{APP_DOMAIN}}/api",
},
});APP_DOMAIN="example.com"At runtime, useRuntimeConfig().url will resolve to "https://example.com/api".