This TypeScript error occurs when the compiler cannot locate a module or its type definitions in your Vite project, often due to incorrect tsconfig.json settings or missing type packages.
This error appears when TypeScript cannot resolve a module import in your Vite project. TypeScript needs to find either the actual module code or separate type declaration files (.d.ts) to provide type checking and IntelliSense. The error is particularly common in Vite projects created with the react-ts template because Vite uses modern module resolution strategies that may conflict with certain TypeScript configurations. When TypeScript encounters an import statement, it follows specific resolution rules based on your tsconfig.json settings to locate the module and its types. The moduleResolution compiler option plays a critical role here. Vite projects work best with "bundler" mode (introduced in TypeScript 5.0), which assumes a bundler will handle module resolution at runtime. However, some packages or configurations may require "node" or "node16" resolution modes instead.
Open your tsconfig.json and verify the moduleResolution setting. For Vite projects, try changing it to "node" if you're experiencing issues with "bundler":
{
"compilerOptions": {
"moduleResolution": "node", // Changed from "bundler"
"module": "ESNext",
"target": "ESNext"
}
}If the error persists, you can also try "node16" or "nodenext" for more modern Node.js resolution:
{
"compilerOptions": {
"moduleResolution": "node16"
}
}After making changes, restart your TypeScript server in VS Code (Ctrl/Cmd + Shift + P → "TypeScript: Restart TS Server").
If the error is for a specific third-party package, check if it has type definitions available:
# For npm
npm install --save-dev @types/package-name
# For yarn
yarn add --dev @types/package-name
# For pnpm
pnpm add -D @types/package-nameFor example, if you're importing lodash:
npm install --save-dev @types/lodashSome packages (like React, Vite plugins) include their own types and don't need separate @types packages.
Vite requires explicit type reference for client-side environment shims. In your tsconfig.json, ensure you include vite/client:
{
"compilerOptions": {
"types": ["vite/client"]
}
}If you have other type packages, add vite/client to the array:
{
"compilerOptions": {
"types": ["vite/client", "node", "jest"]
}
}This provides types for Vite-specific features like import.meta.env and asset imports.
If you're using path aliases, they must be configured in both vite.config.ts and tsconfig.json.
In vite.config.ts:
import { defineConfig } from 'vite';
import path from 'path';
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@components': path.resolve(__dirname, './src/components')
}
}
});In tsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@components/*": ["./src/components/*"]
}
}
}Ensure the paths match exactly between both files.
Make sure TypeScript is tracking the files you're trying to import. Check your tsconfig.json:
{
"include": [
"src/**/*",
"src/**/*.ts",
"src/**/*.tsx",
"vite.config.ts"
],
"exclude": [
"node_modules",
"dist"
]
}If you're importing from a custom directory (e.g., lib/, utils/), ensure it's covered by the include pattern. Add specific paths if needed:
{
"include": [
"src/**/*",
"lib/**/*", // Add custom directories
"types/**/*"
]
}A corrupted or incomplete node_modules directory can cause module resolution failures. Delete it and reinstall:
# Remove existing modules and lock files
rm -rf node_modules
rm package-lock.json # or yarn.lock or pnpm-lock.yaml
# Reinstall
npm install
# or: yarn install
# or: pnpm installFor pnpm specifically, if using symlinks is causing issues, you can add baseUrl to tsconfig.json:
{
"compilerOptions": {
"baseUrl": "./node_modules"
}
}After reinstalling, restart your development server and TypeScript server.
TypeScript 5.0+ and moduleResolution "bundler": The "bundler" module resolution mode was introduced in TypeScript 5.0 specifically for projects using bundlers like Vite, Webpack, or esbuild. It assumes the bundler will handle module resolution and doesn't require file extensions on relative imports. However, some older packages or packages with complex "exports" fields in package.json may not work correctly with this mode.
Package.json "exports" field conflicts: Modern npm packages use the "exports" field to define entry points. TypeScript's bundler mode respects these exports, but if a package has types at a path like /node_modules/package/types/index.d.ts that isn't listed in "exports", TypeScript won't be able to find them. In these cases, switching to "node" or "node16" resolution can help.
skipLibCheck consideration: Vite starter templates set "skipLibCheck": true in tsconfig.json by default. This tells TypeScript to skip type checking of declaration files in node_modules, which can hide type errors from dependencies but speeds up compilation. If you're debugging type resolution issues, temporarily setting this to false may reveal the root cause.
Multiple tsconfig files: Vite projects often have both tsconfig.json (for app code) and tsconfig.node.json (for config files like vite.config.ts). Make sure you're editing the correct one for the file showing the error. Config files should reference tsconfig.node.json, while source files use tsconfig.json.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Vite HMR connection failed, make sure your config is correct
How to fix "Vite HMR connection failed" in React