TypeScript

Nitro is TypeScript-first: write your config, handlers, and server code in TypeScript with zero setup.

Nitro is written in TypeScript and bundles your server code — .ts files work out of the box in development and production, with no separate compile step. The TypeScript compiler is only needed for type checking (for example tsc --noEmit in CI).

All public utilities ship with types:

import { defineConfig } from "nitro";

export default defineConfig({
  // Fully typed config with completions
});

Types (such as NitroConfig, NitroModule, or NitroRuntimeConfig) are exported from nitro/types:

import type { NitroModule } from "nitro/types";

tsconfig.json setup

Nitro provides a shareable TypeScript configuration you can extend from:

tsconfig.json
{
  "extends": "nitro/tsconfig"
}

It enables modern, strict defaults matching how Nitro bundles your code: strict type checking, bundler module resolution, noEmit, verbatimModuleSyntax, and allowImportingTsExtensions (so you can use explicit .ts extensions in imports). You can override any option by adding your own compilerOptions on top:

tsconfig.json
{
  "extends": "nitro/tsconfig",
  "compilerOptions": {
    "jsx": "react-jsx"
  }
}

Generated types

Nitro generates project-specific type declarations based on your routes and configuration. They are written automatically when the dev server starts and on every build, or on demand with nitro prepare.

The files are written to the generated types directory — node_modules/.nitro/types by default (configurable via typescript.generatedTypesDir):

FileContents
nitro.d.tsEntry file referencing the declarations below.
nitro-routes.d.tsReturn types of your route handlers, per route and method.
nitro-config.d.tsRuntime config types (when generateRuntimeConfigTypes is enabled).
nitro-imports.d.tsDeclarations for auto-imports (when enabled).

To make them available to your editor and type checker, add the entry file to your tsconfig include (the explicit path is required since node_modules is excluded by default):

tsconfig.json
{
  "extends": "nitro/tsconfig",
  "include": ["node_modules/.nitro/types/nitro.d.ts", "**/*"]
}
Running nitro prepare in a postinstall script keeps generated types up to date for your editor after each install.

Route types

For each scanned route handler, Nitro records the (JSON-serialized) return type in the InternalApi interface of nitro/types, keyed by route path and HTTP method. Frameworks and libraries can build on this augmentation — together with helper types such as NitroFetchRequest and TypedInternalResponse from nitro/types — to provide end-to-end typed clients for your API.

Runtime config types

By default, useRuntimeConfig() returns a loosely typed object. Enable typescript.generateRuntimeConfigTypes to generate a NitroRuntimeConfig interface from the runtimeConfig values in your config:

import { defineConfig } from "nitro";

export default defineConfig({
  runtimeConfig: {
    apiToken: "dev-token", // Overridable with the NITRO_API_TOKEN environment variable
  },
  typescript: {
    generateRuntimeConfigTypes: true,
  },
});

typescript config options

OptionDefaultDescription
stricttrueEnable strict type checking in the generated tsconfig.
generateRuntimeConfigTypesfalseGenerate types for runtime config.
generateTsConfigfalseWrite a full tsconfig.json into the generated types directory.
tsConfigundefinedOverrides merged into the generated tsconfig. Defaults to your project's root tsconfig.json.
generatedTypesDir"node_modules/.nitro/types"Directory where generated types are written.
tsconfigPath"tsconfig.json"Path of the generated tsconfig, relative to generatedTypesDir.

With generateTsConfig: true, Nitro writes a complete tsconfig.json to the generated types directory — already wired to the generated declarations, your project files, and any tsConfig overrides. You can extend it instead of nitro/tsconfig:

tsconfig.json
{
  "extends": "./node_modules/.nitro/types/tsconfig.json"
}

Auto-imports

Auto-imports are disabled by default in Nitro v3 — explicit imports are recommended for better ecosystem compatibility and clarity. See the migration guide for the list of utilities and where to import them from.

If you prefer auto-imports, opt in by setting the imports option (an object enables them):

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  serverDir: true,
  imports: {},
});

When enabled, exports from the utils/ directory of scanned directories (for example server/utils/) are automatically available in your server code without imports. The imports object accepts unimport options (dirs, presets, exclude, ...) for further customization.

Type declarations for auto-imported utilities are written to nitro-imports.d.ts in the generated types directory — make sure it is referenced from your tsconfig as shown in generated types so your editor recognizes the globals.

Extending types from modules

Modules can hook into type generation with the types:extend build-time hook, which receives the collected types before the declaration files are written:

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  modules: [
    (nitro) => {
      nitro.hooks.hook("types:extend", (types) => {
        types.routes["/api/external"] = { default: ["{ data: string }"] };
      });
    },
  ],
});

The types object contains the per-route type expressions (types.routes) and, when generateTsConfig is enabled, the generated tsconfig (types.tsConfig).