Nuxt auto-generates multiple tsconfig files
Nuxt automatically generates multiple TypeScript configuration files in the .nuxt directory: .nuxt/tsconfig.app.json, .nuxt/tsconfig.server.json, .nuxt/tsconfig.node.json, and .nuxt/tsconfig.shared.json. These files include recommended basic TypeScript configuration, references to auto-imports, API route types, path aliases, and more.
Root tsconfig.json structure with project references
The root tsconfig.json file should contain an empty files array and references to the four auto-generated TypeScript configuration files: .nuxt/tsconfig.app.json, .nuxt/tsconfig.server.json, .nuxt/tsconfig.shared.json, and .nuxt/tsconfig.node.json. Do not modify this file directly as it could overwrite important settings that Nuxt or other modules rely on.
Extend TypeScript configuration via nuxt.config.ts
Customize TypeScript configuration in the nuxt.config.ts file using the typescript property. Use typescript.tsConfig to set shared compilerOptions for all contexts. Use context-specific options to override settings per context: appTsConfig for app context, sharedTsConfig for shared context, nodeTsConfig for node context, and serverTsConfig for server context.
TypeScript compilerOptions sharing across contexts
Most compilerOptions set in typescript.tsConfig are shared with every context, but some are not. DOM- and Vue-specific options (such as lib, jsx, and jsxImportSource) only apply to tsconfig.app.json. Nuxt manages types, paths, and noEmit per context, so setting these in typescript.tsConfig will not change them. Use the matching per-context option (appTsConfig, nodeTsConfig, sharedTsConfig, or serverTsConfig) when you need to override them.
serverTsConfig and nitro.typescript.tsConfig synchronization
typescript.serverTsConfig and nitro.typescript.tsConfig both extend tsconfig.server.json and are kept in sync, so setting either has the same effect. Prefer using typescript.serverTsConfig to keep all four contexts in one place.
Example of extending TypeScript configuration in nuxt.config.ts
export default defineNuxtConfig({
typescript: {
tsConfig: {
compilerOptions: {
// shared compiler options for every generated tsconfig
},
},
appTsConfig: {
// customize tsconfig.app.json
},
sharedTsConfig: {
// customize tsconfig.shared.json
},
nodeTsConfig: {
// customize tsconfig.node.json
},
serverTsConfig: {
// customize tsconfig.server.json
},
},
})
TypeScript support in Vue 3 and Nuxt 3
Both Vue 3 and Nuxt 3+ are written in TypeScript. A fully typed codebase prevents mistakes and documents APIs usage. With Nuxt 3, you can opt-in to TypeScript by renaming your file from .js to .ts, or by adding <script setup lang="ts"> in a component.
Do not modify tsconfig.json directly
It is not recommended to modify your `tsconfig.json` file directly because Nuxt relies on this configuration and Nuxt modules can extend it as well. Doing so could overwrite important settings. Instead, extend it via `nuxt.config.ts`.
Type-checking disabled by default in nuxt dev and build
By default, Nuxt does not check types when you run `nuxt dev` or `nuxt build` for performance reasons. Type-checking must be explicitly enabled.
Enable type-checking with vue-tsc and typescript
To enable type-checking at build or development time, install `vue-tsc` and `typescript` as development dependencies. Then run the `nuxt typecheck` command to check types.
Enable type-checking in nuxt.config
Type-checking can be enabled at build or development time by setting the `typescript.typeCheck` option to true in the `nuxt.config.ts` file.
Auto-generated types in .nuxt directory
Nuxt projects rely on auto-generated types stored in the `.nuxt` directory. These types are generated when you run the dev server or build your application. You can also generate these files manually by running `nuxt prepare`.
Generated tsconfig.json includes recommended configuration
The generated `tsconfig.json` files inside the `.nuxt` directory include recommended basic TypeScript configuration for the project, references to auto-imports, API route types, path aliases like `#imports`, `~/file`, or `#build/file`, and more.
TypeScript project references generated by Nuxt
When you run `nuxt dev`, `nuxt build`, or `nuxt prepare`, Nuxt generates multiple `tsconfig.json` files for different parts of your application: `.nuxt/tsconfig.app.json` for application code in the `app/` directory, `.nuxt/tsconfig.node.json` for `nuxt.config.ts` and files outside other contexts, `.nuxt/tsconfig.server.json` for server-side code, and `.nuxt/tsconfig.shared.json` for code shared between app and server contexts.
Benefits of TypeScript project references
TypeScript project references provide faster builds by skipping rebuilding unchanged projects, better IDE performance with faster IntelliSense and error checking, isolated compilation where errors in one part don't prevent compilation of other parts, and clearer dependency management with each project explicitly declaring its dependencies.
Augment types in correct context with project references
Since the project is divided into multiple type contexts, augmentations must be placed in the correct context. For the `app` context, place augmentation files in the `app/` directory. For the `server` context, place them in the `server/` directory. For types shared between app and server, place the file in the `shared/` directory.
Strict checks enabled by default when type-checking is on
Strict checks are enabled by default in Nuxt when the `typescript.typeCheck` option is enabled, providing greater type safety. Strict checks can be disabled by setting `strict` to `false` in the `nuxt.config` file.
Legacy .nuxt/tsconfig.json maintained for backward compatibility
For backward compatibility, Nuxt still generates `.nuxt/tsconfig.json`. However, using TypeScript project references with the new configuration files (`.nuxt/tsconfig.app.json`, `.nuxt/tsconfig.server.json`, etc.) is recommended for better type safety and performance. The legacy file will be removed in a future version of Nuxt.
Server routes type-checked in both tsconfig.app.json and tsconfig.server.json
Server routes are type-checked using both `tsconfig.app.json` and `tsconfig.server.json`. This is required because Nuxt infers return types of server endpoints to provide response types in `$fetch` and `useFetch`. This can cause issues if server-only types are used in route files, as the app context won't recognize them.
Server-only types workaround for app context type-checking
To avoid type-checking errors when using server-only types in route files, declare such types in the app context as well, not just in `tsconfig.server.json`. This ensures the types are available when the app context type-checks server routes.
TypeScript references bypass tsconfig.json exclude option
TypeScript references add files to the type context without being affected by the `exclude` option in `tsconfig.json`. This means files added via type references will always be included in type-checking regardless of exclude patterns.
typescriptBundlerResolution for TypeScript module resolution
The future.typescriptBundlerResolution option enables 'Bundler' module resolution mode for TypeScript, which is the recommended setting for frameworks like Nuxt and Vite. It improves type support when using modern libraries with exports. The default is false, which uses the legacy 'Node' mode. This is configured in nuxt.config.ts under future.typescriptBundlerResolution.
Typing runtime config with TypeScript
Nuxt automatically generates a TypeScript interface from runtime config using unjs/untyped. Manual typing is also possible by augmenting the RuntimeConfig and PublicRuntimeConfig interfaces from 'nuxt/schema' in a .d.ts file. When augmenting types, always import or export something to ensure the augmentation works.
Server types auto-imported in server context only
Types placed in ~~/server/types/ are auto-imported in the server context only, so you can reference them in server routes, middleware, plugins, and utilities without importing them. Only files directly in server/types/ are scanned; files in nested subdirectories are not auto-imported. Types that are also needed in the Vue app should be placed in `shared/types/` instead.
Example server auto-imported type
```ts
export interface Todo {
id: string
title: string
completed: boolean
}
```
This example shows a type definition placed in server/types/todo.ts that will be auto-imported in the server context and available in server routes without explicit imports.
Example server route using auto-imported type
```ts
import { defineEventHandler } from 'nitro/h3'
export default defineEventHandler((): Todo[] => {
return []
})
```
This example shows a server route using an auto-imported type from server/types/. The Todo type is available without explicit import. This file should be placed in server/api/todos.get.ts.