Absolute Imports & Module Aliases
../../../../components/Button become fragile and hard to read — move a file one level, and every import path pointing to it breaks. Next.js has built-in support for TypeScript's baseUrl and paths settings, letting you write short, absolute import paths instead, resolved from your project root.baseUrl and paths in tsconfig.json
baseUrl defines the root that non-relative imports are resolved from. paths goes a step further, letting you define custom aliases that map to specific folders — the two are often used together.tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"],
"@components/*": ["./src/components/*"],
"@utils/*": ["./src/utils/*"]
}
}
}@/* alias out of the box in new projects (created via create-next-app), pointing at the project root — so @/components/Button typically works immediately, even before adding any custom aliases of your own.Before and after
Before — relative imports
import Button from '../../../../components/common/Button'
import { formatDate } from '../../../utils/date'
import { AppConfig } from '../../../../config'After — absolute imports via aliases
import Button from '@components/common/Button'
import { formatDate } from '@utils/date'
import { AppConfig } from '@config'The second version reads the same regardless of how deeply nested the importing file is, and moving a file no longer requires touching every import that points to it — only the alias mapping (if it changes at all) needs updating.
Custom aliases, one per concern
tsconfig.json — a richer set of aliases
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"],
"@components/*": ["./src/components/*"],
"@hooks": ["./src/hooks"],
"@utils/*": ["./src/utils/*"],
"@config": ["./src/config"]
}
}
}Pattern | Resolves to | Use for |
|---|---|---|
| Project root | General catch-all alias |
|
| UI components |
|
| Helper/utility functions |
|
| App-wide configuration singletons |
baseUrl/paths are set in tsconfig.json, Next.js's compiler and webpack resolver both understand the new paths automatically, and editors like VS Code pick them up for autocomplete and "go to definition" too.Absolute imports are configured entirely in
tsconfig.json— nonext.config.jschanges required.baseUrlsets the root for non-relative imports;pathsdefines named aliases on top of it.New Next.js projects get a default
@/*alias pointing at the project root.Aliases make imports resistant to files moving and easier to scan at a glance.