Mastering React Imports: Relative vs Aliases (../
vs @/
) 🚀
If you’ve ever wondered whether to write:
import { HomePage } from '../features/heroes/HomePage';
…or:
import { HomePage } from '@/features/heroes/HomePage';
You’ve touched on one of those subtle but professional-level React/TypeScript project structuring questions.
Let’s break it down like a senior React developer mentoring their team.
🟢 BASIC — Relative Imports (../
)
Relative imports literally walk the filesystem.
-
..
= “go up one directory”. - So
../features/heroes/HomePage
= “go up one folder, then intofeatures/heroes
”.
âś… Pros
- Works out-of-the-box in Node, React, Vite, Next, etc.
- No extra config needed.
❌ Cons
- Becomes ugly and fragile in deep folder trees:
import { Button } from '../../../../components/ui/Button';
- If you move files, imports break.
- Harder to scan visually: “Where is this pointing to?”
🟡 MEDIUM — Path Aliases (@/
)
Path aliases (aka module aliases) map a symbol (commonly @
) to your src/
folder.
tsconfig.json
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"@/*": ["*"]
}
}
}
vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
});
âś… Pros
- Flat imports regardless of depth:
import { Button } from '@/components/ui/Button';
- Easier to move files around.
- Clear mental model:
@/
= root of your source. - Industry standard in large React / Next.js / Vite apps.
❌ Cons
- Requires config (
tsconfig.json
+ bundler). - New devs must know
@
is a shortcut.
🔵 ADVANCED — Blended Best Practice
As a pro React dev:
-
Use aliases (
@/…
) for imports across feature boundaries or shared libs. - Use relative imports for local siblings inside the same feature.
This keeps features self-contained while global imports stay clean.
Example
// Inside src/features/heroes/HomePage.tsx
import { HeroGrid } from './HeroGrid'; // relative (local sibling)
import { CustomJumbotron } from '@/components/ui'; // alias (shared UI lib)
Result:
✔️ Clarity (local code portable).
✔️ Scalability (global code stays readable).
🟣 EXPERT — The Analogy
Think of it like navigation:
../…
= step-by-step directions
(“go up one block, turn left, go inside”)@/…
= GPS address
(“start from the city center =src/
”)
Both get you there, but one scales much better in a growing city (your project).
⚡ Senior Takeaway
In professional React/Vite/Next projects:
- Always configure
@
(or~
, orsrc
) aliases intsconfig.json
and bundler. - Reserve relative imports for local siblings.
- Use aliases for cross-feature or shared imports.
👉 This keeps codebases readable, maintainable, and resilient to refactors.
✍️ Written by: Cristian Sifuentes — Full-stack React/TypeScript developer, passionate about clean architecture, DX, and teaching dev teams to scale projects like pros.
Top comments (0)