Path aliases let you write import MyComponent from '@/components/MyComponent.vue' instead of import MyComponent from '../../../components/MyComponent.vue'. Vite doesn't set up the @ alias by default, so you get a "Failed to resolve import" error the first time you try it. The fix is two files: vite.config.js (or .ts) and jsconfig.json (or tsconfig.json).
Why use path aliases?
Relative imports like ../../../components/Button.vue work fine in small projects. Once a project grows past a few folders deep, they get hard to read and brittle to refactor. If you move a file, every relative import path in that file breaks. An alias like @ resolves to src/ regardless of where the importing file lives, so moving files is low-friction.
Path aliases in vite.config.js
Configure the alias in the resolve.alias field:
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
})
You can add as many aliases as you like:
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@components': path.resolve(__dirname, './src/components'),
'@utils': path.resolve(__dirname, './src/utils'),
},
},
Once this is set, Vite will resolve @/... imports correctly during the build and in vite dev. The error goes away.
TypeScript projects: vite.config.ts
For TypeScript projects, the config file is vite.config.ts. The __dirname variable is available in Node.js but not typed by default, so use import.meta.url and fileURLToPath instead:
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
})
This is also the format Vite's official scaffolding (npm create vite@latest) generates for Vue TypeScript projects.
Editor intellisense: jsconfig.json and tsconfig.json
Configuring vite.config.js tells Vite's bundler how to resolve paths. Your code editor (VS Code, WebStorm, etc.) uses a separate config for its own path resolution. Without this, imports using @/ won't have autocomplete or go-to-definition.
For JavaScript projects — jsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
For TypeScript projects — tsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
After saving this file, the editor will recognize @/ imports and provide autocomplete.



