
# Features

> Enable and configure Nitro's built-in capabilities such as OpenAPI, plugins, modules, and tasks.

::note
All examples on this page assume the following import in `nitro.config.ts`:

```ts
import { defineConfig } from "nitro";
```
::

### `features`

- Default: `{}`{lang=ts}

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`{lang=ts}

Enable WebSocket support.

:read-more{to="/docs/websocket"}

#### `fastResponse`

- Default: `true`{lang=ts} when [`node`](/config/build#node) is enabled, otherwise `false`{lang=ts}

Replace the global `Response` with srvx `FastResponse`, so `new Response()` in your handlers skips the native `Response` overhead in Node.js. `instanceof Response` keeps working for both native and fast responses.

Has no effect in runtimes without a `FastResponse` implementation (Bun, Deno, workers).

::note
`FastResponse` reads its body and headers lazily and skips some constructor validation. For example, `new Response("body", { status: 204 })` does not throw in Node.js, while it does in other runtimes. Set `fastResponse: false` to use the native `Response`.
::

```ts
export default defineConfig({
  features: {
    runtimeHooks: true,
    websocket: true, // enable WebSocket support
    fastResponse: false, // use the native global Response
  },
});
```

### `experimental`

- Default: `{}`{lang=ts}

Enable experimental features.

#### `openAPI`

- Default: `false`{lang=ts}

Enable `/_scalar`, `/_swagger` and `/_openapi.json` endpoints.

::note
Prefer using the top-level [`openAPI`](#openapi) option for configuration.
::

#### `typescriptBundlerResolution`

Enable TypeScript bundler module resolution. See [TypeScript#51669](https://github.com/microsoft/TypeScript/pull/51669).

::note
This flag currently has no effect: bundler module resolution is always used by `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](/docs/configuration#env-expansion) and [#2043](https://github.com/nitrojs/nitro/pull/2043).

#### `database`

Enable experimental database support. See [Database](/docs/database).

#### `tasks`

Enable experimental tasks support. See [Tasks](/docs/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, db0, ...). Requires [`tracingChannel`](/config/advanced#tracingchannel) to be enabled.

```ts
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:

```js
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.

```js
openAPI: {
    // IMPORTANT: make sure to protect OpenAPI routes if necessary!
    production: "runtime", // or "prerender"
}
```

To customize the Scalar integration, [pass a configuration object](https://github.com/scalar/scalar) like this:

```js
openAPI: {
  ui: {
    scalar: {
      theme: 'purple'
    }
  }
}
```

To customize the Swagger UI, pass any [Swagger UI configuration option](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/):

```js
openAPI: {
  ui: {
    swagger: {
      persistAuthorization: true,
      deepLinking: true,
      docExpansion: 'none',
      filter: true,
    }
  }
}
```

To customize the endpoints:

```js
openAPI: {
  route: "/_docs/openapi.json",
  ui: {
    scalar: {
      route: "/_docs/scalar"
    },
    swagger: {
      route: "/_docs/swagger"
    }
  }
}
```

:read-more{to="/docs/openapi"}

### `renderer`

- Type: `false`{lang=ts} | `{ handler?: string, static?: boolean, template?: string }`{lang=ts}

Points to main render entry (file should export an event handler as default).

```ts
export default defineConfig({
  renderer: {
    handler: "~/renderer", // path to the render handler
  },
});
```

:read-more{to="/docs/renderer"}

### `ssrRoutes`

Routes that should be server-side rendered.

```ts
export default defineConfig({
  ssrRoutes: ["/app/**"],
});
```

### `modules`

- Default: `[]`{lang=ts}

An array of Nitro modules. Modules can be a string (path), a module object with a `setup` function, or a function.

```ts
export default defineConfig({
  modules: [
    "./modules/my-module.ts",
    (nitro) => {
      nitro.hooks.hook("compiled", () => { /* ... */ });
    },
  ],
});
```

### `plugins`

- Default: `[]`{lang=ts}

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.

```ts
export default defineConfig({
  plugins: [
    "~/plugins/my-plugin.ts",
  ],
});
```

:read-more{to="/docs/plugins"}

### `tasks`

- Default: `{}`{lang=ts}

Task definitions. Each key is a task name with an optional `handler` path and `description`.

Tasks scanned from `<serverDir>/tasks/` only need a `description` here. A `handler` is imported as-is and is not resolved against the project root, so it has to be an absolute path or a package name.

```ts
import { fileURLToPath } from "node:url";

export default defineConfig({
  tasks: {
    "db:migrate": {
      description: "Run database migrations",
    },
    "db:seed": {
      handler: fileURLToPath(new URL("scripts/seed.ts", import.meta.url)),
      description: "Seed the database",
    },
  },
});
```

:read-more{to="/docs/tasks"}

### `scheduledTasks`

- Default: `{}`{lang=ts}

Map of cron expressions to task name(s).

```ts
export default defineConfig({
  scheduledTasks: {
    "0 * * * *": "cleanup:temp",
    "*/5 * * * *": ["health:check", "metrics:collect"],
  },
});
```

:read-more{to="/docs/tasks"}

### `virtual`

- Default: `{}`{lang=ts}

A map from dynamic virtual import names to their contents or an (async) function that returns it.

```ts
export default defineConfig({
  virtual: {
    "#config": `export default { version: "1.0.0" }`,
  },
});
```

### `wasm`

- Type: `false`{lang=ts} | `UnwasmPluginOptions`{lang=ts}
- Default: `{}`{lang=ts}

WASM support configuration. See [unwasm](https://github.com/unjs/unwasm) for options.

```ts
export default defineConfig({
  wasm: {}, // enable WASM import support
});
```
