Stop Wrestling with Relative Imports: Master Absolute Imports in React + TypeScript + Vite
Tired of seeing ../../../components/Button in your React imports? Absolute imports are your solution for cleaner, more maintainable code. Here's how t

Search for a command to run...
Tired of seeing ../../../components/Button in your React imports? Absolute imports are your solution for cleaner, more maintainable code. Here's how t

No comments yet. Be the first to comment.
That time I reverse engineered an AI startup to prove a point.

When all your colleagues are remote, how to communicate effectively to avoid conflicts and confusions.

Hey Dumbfuck, this is how you set an image saved localy as background with Tailwind in a NextJS project

In this blog, I am keeping a draft example of the modern tsconfig file that works for me in the projects that I am making. { "compilerOptions": { "target": "ESNext", "experimentalDecorators": false, "module": "commonjs", "rootDir": ...
The difference is immediately clear.
Before (Relative Imports):
TypeScript
import Button from '../../../components/ui/Button'
import { useAuth } from '../../../../hooks/useAuth'
import logo from '../../assets/images/logo.svg'
After (Absolute Imports):
TypeScript
import Button from '@/components/ui/Button'
import { useAuth } from '@/hooks/useAuth'
import logo from '@/assets/images/logo.svg'
No more path confusion when moving files.
Cleaner, more readable import statements.
Easier refactoring and file organization.
Consistent imports across your entire project.
To get absolute imports working, you need to tell both TypeScript (for type checking and autocompletion) and Vite (your bundler) how to resolve these new paths.
tsconfig.jsonThis is the root TypeScript config. We just need to ensure it references our other TypeScript configurations. The key settings for path aliases will go in tsconfig.app.json.
JSON
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}
tsconfig.app.jsonThis file configures TypeScript for your application code. Here we define the baseUrl and paths so that TypeScript understands the @ alias.
JSON
{
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2022",
"useDefineForClassFields": true,
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Path Alias Configuration */
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
vite.config.tsFinally, update your Vite configuration to resolve the path aliases during the build and development process.
TypeScript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
}
}
})
Install @types/node (required for using path and __dirname in vite.config.ts):
Bash
npm install -D @types/node
Copy the configurations above into your respective files (tsconfig.json, tsconfig.app.json, and vite.config.ts).
Restart your development server:
Bash
npm run dev
Restart the TypeScript server in your IDE (In VS Code: Cmd + Shift + P → "TypeScript: Restart TS Server").
Now you can use clean, absolute paths everywhere in your project.
TypeScript
// Components
import Header from '@/components/Header'
import Button from '@/components/ui/Button'
// Assets
import logo from '@/assets/logo.svg'
import heroImage from '@/assets/images/hero.jpg'
// Utils & Hooks
import { formatDate } from '@/utils/date'
import { useAuth } from '@/hooks/useAuth'
"baseUrl": ".": This tells the TypeScript compiler that the root for path resolution is the project's root directory (where tsconfig.json is located).
"@/*": ["src/*"]: This is the path mapping. It tells TypeScript that any import starting with @/ should be mapped to the src/ directory.
path.resolve(__dirname, './src'): This is used in vite.config.ts to create a reliable, absolute file path to your src directory, ensuring Vite can find the files correctly regardless of the operating system.
Your imports are now cleaner, your code is more maintainable, and file reorganization is effortless. No more counting ../ levels!