Why Separate Configuration Exists
In a modern Vite project using React and TypeScript, the project structure typically includes two distinct environments: the client-side browser application and the server-side build tooling. The tsconfig.json file is primarily designed for the client-side code, which runs in the browser. However, Vite itself is a Node.js application during the build process. To handle this distinction cleanly, Vite generates a separate tsconfig.node.json file.
This separation allows developers to specify different compiler options for each context. For instance, the browser environment might target older JavaScript versions for compatibility, while the Node.js build process can utilize the latest features without worrying about legacy browser support. This isolation prevents conflicts between what the browser understands and what the build tool requires.
Key Differences in Compiler Options
The primary difference between tsconfig.json and tsconfig.node.json lies in their target and module settings. In tsconfig.node.json, the target is usually set to ESNext or a recent version of ECMAScript because Node.js supports these modern standards. Additionally, the module resolution strategy is often set to NodeNext or CommonJS depending on the Node.js version and package type, ensuring that imports in configuration files resolve correctly.
Conversely, tsconfig.json might target ES2015 or ES2020 and use DOM lib types to provide access to browser APIs like window or document. By keeping these configurations separate, you avoid including DOM-specific types in your build scripts, which could lead to errors if those scripts run in a pure Node.js environment without a DOM.
How Vite Uses the File
Vite automatically detects the presence of tsconfig.node.json when it processes configuration files such as vite.config.ts. When you import dependencies or define plugins in these files, Vite uses the settings in tsconfig.node.json to transpile the TypeScript code into JavaScript that Node.js can execute. This happens seamlessly during the startup of the development server or the production build.
If you remove tsconfig.node.json, Vite may fall back to the main tsconfig.json. This can cause issues if the main configuration includes strict browser-specific checks or excludes certain Node.js built-in modules. Ensuring the dedicated file exists helps maintain a clear boundary between your application logic and your build infrastructure.
Customizing the Configuration
You can customize tsconfig.node.json to suit specific needs, such as enabling stricter type checking for your configuration files. For example, you might want to enable noImplicitAny or strictNullChecks specifically for your build scripts to catch potential errors early. Since these files are less likely to change frequently than your component code, stricter rules here can improve overall project stability.
To modify the file, simply edit the JSON object. You can extend the base configuration if needed, though Vite’s default setup is usually sufficient for most React projects. If you encounter issues with module resolution in your config files, check that the moduleResolution setting aligns with your Node.js version.
Related Troubleshooting
If you face issues connecting your HTML entry point to your React components, refer to our guide on Troubleshooting Vite + React: Connecting index.html to main.jsx. Additionally, if you are trying to add TypeScript to an existing project and need help managing UI elements, see How to Find and Hide the 'Add TypeScript' Button.
Frequently Asked Questions
Can I delete tsconfig.node.json?
Yes, but Vite will then use the main tsconfig.json for both client and build code. This may lead to type errors if your client config includes DOM-specific settings incompatible with Node.js.
Why does my vite.config.ts have red underlines?
This often happens if tsconfig.node.json is missing or misconfigured. Ensure it targets ESNext and uses appropriate module resolution for your Node.js environment.
Should I share extends between both files?
It is common to have both files extend a shared tsconfig.base.json. This reduces duplication while allowing each environment to override specific settings like target or lib.
Does this affect production builds?
No, the separation mainly impacts how TypeScript compiles your configuration files during development and build time. The final output sent to the browser remains unaffected by these internal compiler choices.
Can I use ESM in tsconfig.node.json?
Yes, if your package.json has "type": "module", you can set the module field to "ESNext" in tsconfig.node.json to support ES Module syntax in your config files.