Config
nitro.config.ts:import { defineConfig } from "nitro";
General
Core options for presets, logging, and runtime configuration.
preset
The deployment preset to build for in production. Can also be set with the NITRO_PRESET environment variable.
The preset for development mode is always nitro_dev. For production, the default is node_server, which builds a standalone Node.js server.
When the preset option is not set and Nitro is running in a known environment, the preset is detected automatically.
export default defineConfig({
preset: "cloudflare_pages", // deploy to Cloudflare Pages
});
defaultPreset
Customize the preset used as the fallback when preset is not set and none of the known hosting providers are auto-detected.
By default, Nitro falls back to the runtime-based preset (node, and deno or bun when running on those runtimes). An explicit preset, the NITRO_PRESET environment variable, and auto-detected providers (Vercel, Netlify, Cloudflare Pages, ...) all take precedence over defaultPreset.
It accepts a preset name or an inline preset definition.
export default defineConfig({
defaultPreset: "node_cluster", // use node_cluster instead of node_server by default
});
debug
- Default:
false(truewhenDEBUGenvironment variable is set)
Enable debug mode for verbose logging and additional development information.
export default defineConfig({
debug: true,
});
logLevel
- Default:
3(1when the testing environment is detected)
Log verbosity level. See consola for more information.
export default defineConfig({
logLevel: 4, // verbose logging
});
runtimeConfig
- Default:
{ app: {}, nitro: {} }
Server runtime configuration. Nitro injects app.baseURL (from the baseURL option) into the app namespace.
Note: The app and nitro namespaces are reserved for internal use.
export default defineConfig({
runtimeConfig: {
apiSecret: "default-secret", // override with NITRO_API_SECRET
},
});
compatibilityDate
- Default:
"latest"behavior when not provided
Deployment providers introduce new features that Nitro presets can leverage, but some of them need to be explicitly opted into. Set this to the latest date you have tested against, in YYYY-MM-DD format, to leverage the latest preset features.
export default defineConfig({
compatibilityDate: "2025-01-01",
});
static
- Default:
false
Enable static site generation mode.
export default defineConfig({
static: true, // prerender all routes
});
Features
Enable and configure Nitro's built-in capabilities such as storage, tasks, and assets.
features
- Default:
{}
Enable built-in features.
runtimeHooks
- Default: auto-detected (enabled if there is at least one nitro plugin)
Enable runtime hooks for request and response.
websocket
- Default:
false
Enable WebSocket support.
export default defineConfig({
features: {
runtimeHooks: true,
websocket: true, // enable WebSocket support
},
});
experimental
- Default:
{}
Enable experimental features.
openAPI
- Default:
false
Enable /_scalar, /_swagger and /_openapi.json endpoints.
openAPI option for configuration.typescriptBundlerResolution
Enable TypeScript bundler module resolution. See TypeScript#51669.
nitro/tsconfig and the generated tsconfig.asyncContext
Enable native async context support for useRequest().
sourcemapMinify
Set to false to disable experimental sourcemap minification (enabled by default when sourcemap is enabled).
envExpansion
Allow env expansion in runtime config. See the configuration guide and #2043.
database
Enable experimental database support. See Database.
tasks
Enable experimental tasks support. See Tasks.
tracingLogger
Log Nitro tracing-channel spans to the console using a built-in, dependency-free telemetry sink that logs each completed span (h3, srvx, unstorage, ...). Requires tracingChannel to be enabled.
export default defineConfig({
experimental: {
typescriptBundlerResolution: true,
asyncContext: true,
envExpansion: true,
database: true,
tasks: true,
},
});
openAPI
Top-level OpenAPI configuration.
You can pass an object to modify your OpenAPI specification:
openAPI: {
meta: {
title: 'My Awesome Project',
description: 'This might become the next big thing.',
version: '1.0'
}
}
These routes are disabled by default in production. To enable them, use the production key.
"runtime" allows middleware usage, and "prerender" is the most efficient because the JSON response is constant.
openAPI: {
// IMPORTANT: make sure to protect OpenAPI routes if necessary!
production: "runtime", // or "prerender"
}
To customize the Scalar integration, pass a configuration object like this:
openAPI: {
ui: {
scalar: {
theme: 'purple'
}
}
}
To customize the Swagger UI, pass any Swagger UI configuration option:
openAPI: {
ui: {
swagger: {
persistAuthorization: true,
deepLinking: true,
docExpansion: 'none',
filter: true,
}
}
}
To customize the endpoints:
openAPI: {
route: "/_docs/openapi.json",
ui: {
scalar: {
route: "/_docs/scalar"
},
swagger: {
route: "/_docs/swagger"
}
}
}
future
- Default:
{}
New features pending for a major version to avoid breaking changes.
nativeSWR
Uses built-in SWR functionality (using caching layer and storage) for Netlify and Vercel presets instead of falling back to ISR behavior.
export default defineConfig({
future: {
nativeSWR: true,
},
});
storage
- Default:
{}
Storage configuration.
export default defineConfig({
storage: {
redis: {
driver: "redis",
url: "redis://localhost:6379",
},
},
});
devStorage
- Default:
{}
Storage configuration overrides for development mode.
export default defineConfig({
devStorage: {
redis: {
driver: "fs",
base: "./data/redis", // use filesystem in development
},
},
});
database
Database connection configurations. Requires experimental.database: true.
export default defineConfig({
database: {
default: {
connector: "sqlite",
options: { name: "db" },
},
},
});
devDatabase
Database connection configuration overrides for development mode.
export default defineConfig({
devDatabase: {
default: {
connector: "sqlite",
options: { name: "db-dev" }, // separate dev database
},
},
});
renderer
- Type:
false|{ handler?: string, static?: boolean, template?: string }
Points to main render entry (file should export an event handler as default).
export default defineConfig({
renderer: {
handler: "~/renderer", // path to the render handler
},
});
ssrRoutes
Routes that should be server-side rendered.
export default defineConfig({
ssrRoutes: ["/app/**"],
});
serveStatic
- Type:
boolean|'node'|'inline' - Default: depends on the deployment preset used.
Serve public/ assets in production.
Note: It is highly recommended that your edge CDN (Nginx, Apache, Cloud) serves the .output/public/ directory instead to enable compression and higher level caching.
export default defineConfig({
serveStatic: "node", // serve static assets using Node.js
});
noPublicDir
- Default:
false
If enabled, disables .output/public directory creation. Skips copying public/ dir and also disables pre-rendering.
export default defineConfig({
noPublicDir: true, // skip public directory output
});
publicAssets
Public asset directories to serve in development and bundle in production.
If a public/ directory is detected, it will be added by default, but you can add more by yourself too!
It's possible to set Cache-Control headers for assets using the maxAge option:
export default defineConfig({
publicAssets: [
{
baseURL: "images",
dir: "public/images",
maxAge: 60 * 60 * 24 * 7, // 7 days
},
],
});
The config above generates the following header in the assets under public/images/ folder:
cache-control: public, max-age=604800, immutable
The dir option is where your files live on your file system; the baseURL option is the folder they will be accessible from when served/bundled.
compressPublicAssets
- Type:
boolean|{ gzip?: boolean, brotli?: boolean, zstd?: boolean } - Default:
false
If enabled, Nitro will generate a pre-compressed (gzip, brotli, and/or zstd) version of supported types of public assets and prerendered routes larger than 1024 bytes into the public directory. Default compression levels are used. Using this option you can support zero overhead asset compression without using a CDN.
export default defineConfig({
compressPublicAssets: {
gzip: true,
brotli: true, // enable gzip and brotli pre-compression
},
});
serverAssets
Assets can be accessed in server logic and bundled in production.
export default defineConfig({
serverAssets: [
{
baseName: "templates",
dir: "./templates", // bundle templates/ as server assets
},
],
});
modules
- Default:
[]
An array of Nitro modules. Modules can be a string (path), a module object with a setup function, or a function.
export default defineConfig({
modules: [
"./modules/my-module.ts",
(nitro) => {
nitro.hooks.hook("compiled", () => { /* ... */ });
},
],
});
plugins
- Default:
[]
An array of paths to nitro plugins. They will be executed in order on the first initialization.
Note that Nitro auto-registers the plugins in the plugins/ directory.
export default defineConfig({
plugins: [
"~/plugins/my-plugin.ts",
],
});
tasks
- Default:
{}
Task definitions. Each key is a task name with a handler path and optional description.
export default defineConfig({
tasks: {
"db:migrate": {
handler: "./tasks/db-migrate",
description: "Run database migrations",
},
},
});
scheduledTasks
- Default:
{}
Map of cron expressions to task name(s).
export default defineConfig({
scheduledTasks: {
"0 * * * *": "cleanup:temp",
"*/5 * * * *": ["health:check", "metrics:collect"],
},
});
imports
- Default:
false
Auto import options. Set to an object to enable. See unimport for more information.
export default defineConfig({
imports: {
dirs: ["./utils"], // auto-import from utils/ directory
},
});
virtual
- Default:
{}
A map from dynamic virtual import names to their contents or an (async) function that returns it.
export default defineConfig({
virtual: {
"#config": `export default { version: "1.0.0" }`,
},
});
ignore
- Default:
[]
Array of glob patterns to ignore when scanning directories.
export default defineConfig({
ignore: [
"routes/_legacy/**", // skip legacy route handlers
],
});
wasm
- Type:
false|UnwasmPluginOptions - Default:
{}
WASM support configuration. See unwasm for options.
export default defineConfig({
wasm: {}, // enable WASM import support
});
Dev
Options that only affect the development server (nitro dev).
devServer
- Default:
{ watch: [] }
Dev server options. You can use watch to make the dev server reload if any file changes in specified paths.
Supports port, hostname, watch, and runner options.
export default defineConfig({
devServer: {
port: 3001,
watch: ["./server/plugins"],
},
});
watchOptions
Watch options for development mode. See chokidar for more information.
export default defineConfig({
watchOptions: {
ignored: ["**/node_modules/**", "**/dist/**"],
},
});
devProxy
Proxy configuration for development server.
You can use this option to override development server routes and proxy-pass requests.
export default defineConfig({
devProxy: {
"/proxy/test": "http://localhost:3001",
"/proxy/example": { target: "https://example.com", changeOrigin: true },
},
});
See httpxy for all available target options.
Logging
logging
- Default:
{ compressedSizes: true, buildSuccess: true }
Control build logging behavior. Set compressedSizes to false to skip reporting compressed bundle sizes. Set buildSuccess to false to suppress the build success message.
export default defineConfig({
logging: {
compressedSizes: false, // skip compressed size reporting
buildSuccess: false,
},
});
Routing
Options for defining routes, handlers, and route-level behavior.
baseURL
- Default:
"/"(orNITRO_APP_BASE_URLenvironment variable if provided)
Server's main base URL.
export default defineConfig({
baseURL: "/app/", // serve app under /app/ prefix
});
apiBaseURL
- Default:
"/api"
Changes the default API base URL prefix.
export default defineConfig({
apiBaseURL: "/server/api", // api routes under /server/api/
});
serverEntry
- Type:
false|string|{ handler: string, format?: EventHandlerFormat }
Custom server entry point configuration. Set to false to disable the default server entry.
export default defineConfig({
serverEntry: "./server.ts",
});
handlers
Server handlers and routes.
If routes/, api/ or middleware/ directories exist inside the server directory, they will be automatically added to the handlers array.
export default defineConfig({
handlers: [
{ route: "/health", handler: "./handlers/health.ts" },
{ route: "/admin/**", handler: "./handlers/admin.ts", method: "get" },
],
});
devHandlers
Handlers provided as programmatic instances instead of file paths. Unlike regular handlers, which are imported and transformed by the bundler, devHandlers accept a handler function directly.
Note: They are only available in development mode and not in the production build.
export default defineConfig({
devHandlers: [
{ route: "/__dev", handler: defineHandler(() => "dev-only route") },
],
});
routes
- Default:
{}
Inline route definitions. A map from route pattern to handler path or handler options.
export default defineConfig({
routes: {
"/hello": "./routes/hello.ts",
"/greet": { handler: "./routes/greet.ts", method: "post" },
},
});
errorHandler
- Type:
string|string[]
Path(s) to custom runtime error handler(s). Replaces nitro's built-in error page.
import { defineConfig } from "nitro";
export default defineConfig({
errorHandler: "~/error",
});
import { defineErrorHandler } from "nitro";
export default defineErrorHandler((error, event) => {
return new Response('[custom error handler] ' + error.stack, {
headers: { 'Content-Type': 'text/plain' }
});
});
routeRules
🧪 Experimental!
Route options. It is a map from route pattern (following rou3) to route options.
When cache option is set, handlers matching pattern will be automatically wrapped with defineCachedHandler.
See the Cache API for all available cache options.
swr: true|number is shortcut for cache: { swr: true, maxAge: number }routeRules: {
'/blog/**': { swr: true },
'/feed/**': { swr: 600 },
'/docs/**': { static: true },
'/dashboard/**': { cache: { /* cache options*/ } },
'/assets/**': { headers: { 'cache-control': 's-maxage=0' } },
'/api/v1/**': { cors: true, headers: { 'access-control-allow-methods': 'GET' } },
'/old-page': { redirect: '/new-page' }, // uses status code 307 (Temporary Redirect)
'/old-page2': { redirect: { to:'/new-page2', statusCode: 301 } },
'/old-page/**': { redirect: '/new-page/**' },
'/proxy/example': { proxy: 'https://example.com' },
'/proxy/**': { proxy: '/api/**' },
'/admin/**': { basicAuth: { username: 'admin', password: 'secret' } },
}
prerender
Prerendering options. Any route specified will be fetched during the build and copied to the .output/public directory as a static asset.
Default:
{
autoSubfolderIndex: true,
concurrency: 1,
interval: 0,
failOnError: false,
crawlLinks: false,
ignore: [],
routes: [],
retry: 3,
retryDelay: 500
}
Any route (string) that starts with a prefix listed in ignore, or matches a regular expression or function, will be ignored.
If the crawlLinks option is set to true, nitro starts with / by default (or all routes in the routes array), extracts <a> tags from HTML pages, and prerenders them as well.
You can set the failOnError option to true to stop the CI when Nitro could not prerender a route.
The interval and concurrency options let you control the speed of prerendering, which can be useful to avoid rate limits when calling external APIs.
The autoSubfolderIndex option controls how files are generated in the .output/public directory:
# autoSubfolderIndex: true (default)
/about -> .output/public/about/index.html
# autoSubfolderIndex: false
/about -> .output/public/about.html
This option is useful when your hosting provider does not give you an option regarding the trailing slash.
The prerenderer will attempt to render pages 3 times with a delay of 500ms. Use retry and retryDelay to change this behavior.
Set ignoreUnprefixedPublicAssets to true to skip prerendering public assets that do not have a base URL prefix.
Directories
Customize where Nitro looks for source files and writes its output.
workspaceDir
Project workspace root directory.
The workspace directory (e.g. pnpm workspace) is automatically detected when the workspaceDir option is not set.
export default defineConfig({
workspaceDir: "../", // monorepo root
});
rootDir
Project main directory.
export default defineConfig({
rootDir: "./src/server",
});
serverDir
- Type:
boolean|"./"|"./server"|string - Default:
false
Server directory for scanning api/, routes/, plugins/, utils/, middleware/, modules/, and tasks/ folders.
When set to false, automatic directory scanning is disabled. Set to "./" to use the root directory, or "./server" to use a server/ subdirectory.
export default defineConfig({
serverDir: "./server", // scan server/ subdirectory
});
scanDirs
- Default:
[](the server source directory is scanned when empty)
List of directories to scan and auto-register files, such as API routes.
export default defineConfig({
scanDirs: ["./modules/auth/api", "./modules/billing/api"],
});
apiDir
- Default:
"api"
Defines a different directory to scan for api route handlers.
export default defineConfig({
apiDir: "endpoints", // scan endpoints/ instead of api/
});
routesDir
- Default:
"routes"
Defines a different directory to scan for route handlers.
export default defineConfig({
routesDir: "pages", // scan pages/ instead of routes/
});
buildDir
- Default:
"node_modules/.nitro"
Nitro's temporary working directory for generating build-related files.
export default defineConfig({
buildDir: ".nitro", // use .nitro/ in project root
});
output
- Default:
{ dir: '.output', serverDir: '.output/server', publicDir: '.output/public' }
Output directories for production bundle.
export default defineConfig({
output: {
dir: "dist",
serverDir: "dist/server",
publicDir: "dist/public",
},
});
Build
Bundler selection and build output tuning.
builder
- Type:
"rollup"|"rolldown"|"vite" - Default:
undefined(auto-detected)
Specify the bundler to use for building.
export default defineConfig({
builder: "vite",
});
rollupConfig
Additional rollup configuration.
export default defineConfig({
rollupConfig: {
output: { manualChunks: { vendor: ["lodash-es"] } },
},
});
rolldownConfig
Additional rolldown configuration.
export default defineConfig({
rolldownConfig: {
output: { banner: "/* built with nitro */" },
},
});
entry
Bundler entry point.
export default defineConfig({
entry: "./server/entry.ts", // custom entry file
});
unenv
unenv preset(s) for environment compatibility.
export default defineConfig({
unenv: {
alias: { "my-module": "my-module/web" },
},
});
alias
Path aliases for module resolution.
export default defineConfig({
alias: {
"~utils": "./src/utils",
"#shared": "./shared",
},
});
minify
- Default:
false
Minify bundle.
export default defineConfig({
minify: true, // minify production bundle
});
inlineDynamicImports
- Default:
false
Bundle all code into a single file instead of creating separate chunks per route.
When false, each route handler becomes a separate chunk loaded on-demand. When true, everything is bundled together. Some presets enable this by default.
export default defineConfig({
inlineDynamicImports: true, // single output file
});
sourcemap
- Default:
false
Enable source map generation. See options.
export default defineConfig({
sourcemap: true, // generate .map files
});
node
- Default:
true
Specify whether the build is used for Node.js or not. If set to false, nitro tries to mock Node.js dependencies using unenv and adjust its behavior.
export default defineConfig({
node: false, // target non-Node.js runtimes
});
replace
Build-time string replacements.
export default defineConfig({
replace: {
"process.env.APP_VERSION": JSON.stringify("1.0.0"),
},
});
commonJS
Specifies additional configuration for the rollup CommonJS plugin.
export default defineConfig({
commonJS: {
requireReturnsDefault: "auto",
},
});
exportConditions
Custom export conditions for module resolution.
export default defineConfig({
exportConditions: ["worker", "production"],
});
noExternals
- Default:
false
Prevent specific packages from being externalized. Set to true to bundle all dependencies, or pass an array of package names/patterns.
export default defineConfig({
noExternals: true, // bundle all dependencies
});
traceDeps
- Default:
[]
Additional dependencies to trace and include in the build output.
Supports special prefixes:
!pkg— Exclude a built-in package from tracing.pkg*— Full trace: copies all package files instead of only traced ones.
export default defineConfig({
traceDeps: [
"sharp",
"better-sqlite3",
"my-pkg*", // full trace (copy all package files)
"!unwanted-pkg", // exclude from tracing
],
});
traceOpts
Advanced options passed to nf3 for dependency tracing.
export default defineConfig({
traceOpts: {
// Options passed to @vercel/nft for file tracing
nft: { /* ... */ },
// Alias for module paths when tracing
traceAlias: { "old-pkg": "new-pkg" },
// Preserve or set file permissions when copying (true or octal like 0o755)
chmod: true,
// Transform traced files before copying
transform: [
{ filter: (id) => id.endsWith(".js"), handler: (code) => code },
],
// Hook into tracing lifecycle
hooks: {
tracedPackages(pkgs) {
console.log("Traced packages:", Object.keys(pkgs));
},
},
},
});
oxc
OXC options for rolldown builds. Includes minify and transform sub-options.
export default defineConfig({
oxc: {
minify: { compress: true, mangle: true },
},
});
Advanced
Low-level options — most projects should not need to change these.
dev
- Default:
truefor development andfalsefor production
export default defineConfig({
dev: true, // force development mode behavior
});
typescript
- Default:
{ strict: true, generateRuntimeConfigTypes: false, generateTsConfig: false }
TypeScript configuration options including strict, generateRuntimeConfigTypes, generateTsConfig, tsConfig, generatedTypesDir, and tsconfigPath.
export default defineConfig({
typescript: {
strict: true,
generateTsConfig: true,
},
});
hooks
Nitro hooks. See hookable for more information.
export default defineConfig({
hooks: {
compiled(nitro) {
console.log("Build compiled successfully!");
},
},
});
commands
Preview and deploy command hints are usually filled by deployment presets.
export default defineConfig({
commands: {
preview: "node ./server/index.mjs",
},
});
devErrorHandler
A custom error handler function for development errors.
export default defineConfig({
devErrorHandler: (error, event) => {
return new Response(`Dev error: ${error.message}`, { status: 500 });
},
});
tracingChannel
🧪 Experimental!
- Type:
boolean|{ srvx?: boolean, h3?: boolean, unstorage?: boolean } - Default:
false
The tracingChannel option enables TracingChannel instrumentation for request handling. It is wired for Node.js and also works in Bun, Deno, and the development preset — any runtime that exposes node:diagnostics_channel. The published srvx.request and h3.request channels remain available across these runtimes and can be consumed by APM tools and custom subscribers.
Pass true to enable both channels, or an object to toggle them individually.
export default defineConfig({
tracingChannel: true,
});
framework
- Default:
{ name: "nitro", version: "<current>" }
Framework information. Used by presets and build info. Typically set by higher-level frameworks (e.g. Nuxt).
export default defineConfig({
framework: { name: "my-framework", version: "2.0.0" },
});
manifest
Build manifest options. Use deploymentId to include a custom deployment identifier in the build manifest (some presets fill it automatically from platform environment variables).
export default defineConfig({
manifest: { deploymentId: process.env.DEPLOY_ID },
});
Preset options
Provider-specific options, applied when the matching deployment preset is used.
awsAmplify
The options for the AWS Amplify preset. Main fields are catchAllStaticFallback, imageOptimization (path, cacheControl), imageSettings, and runtime (nodejs20.x | nodejs22.x | nodejs24.x). See Preset Docs.
export default defineConfig({
awsAmplify: {
runtime: "nodejs22.x",
imageOptimization: { path: "/_image", cacheControl: "public, max-age=3600" },
},
});
awsLambda
The options for the AWS Lambda preset. Set streaming to true to enable response streaming. See Preset Docs.
export default defineConfig({
awsLambda: {
streaming: true,
},
});
azure
The options for the Azure Static Web Apps preset. Use config to customize the generated staticwebapp.config.json (e.g. platform.apiRuntime, navigationFallback). See Preset Docs.
export default defineConfig({
azure: {
config: { platform: { apiRuntime: "node:20" } },
},
});
firebase
The options for the Firebase Functions preset. See Preset Docs.
export default defineConfig({
firebase: {
gen: 2, // use Cloud Functions 2nd gen
region: "us-central1",
},
});
iis
The options for the IIS presets. Use mergeConfig to merge the generated web.config with an existing one, or overrideConfig to replace it entirely. See Preset Docs.
export default defineConfig({
iis: {
mergeConfig: true,
},
});
netlify
The options for the Netlify presets. Use config to provide Netlify deploy configuration (headers, redirects, functions, edge_functions, images, ...). See Preset Docs.
export default defineConfig({
netlify: {
config: {
redirects: [{ from: "/old", to: "/new", status: 301 }],
},
},
});
vercel
The options for the Vercel preset. See Preset Docs.
export default defineConfig({
vercel: {
config: { runtime: "nodejs20.x" },
},
});
cloudflare
The options for the Cloudflare preset. See Preset Docs.
export default defineConfig({
cloudflare: {
wrangler: { compatibility_date: "2025-01-01" },
},
});
zephyr
The options for the Zephyr preset. See Preset Docs.