Path Aliases That Don’t Break Production (@/ Without Regret)
How to use tsconfig paths safely across Next.js, bundlers, Node scripts, and tsc builds—without ‘works locally, fails in prod’.
Frontend Interview Team
March 01, 2026
What you’ll learn
- What
baseUrl+pathsactually do (and what they don’t do) - Why TS path aliases can compile but fail at runtime
- Safe patterns for Next.js, bundlers, and Node scripts
- A production checklist to keep aliases boring
30‑second interview answer
tsconfig.paths only affects TypeScript’s type-checker (and some tooling). It does not rewrite runtime imports. Your runtime (Node) or bundler (Next/Vite/Webpack) must also understand the alias, otherwise you get runtime MODULE_NOT_FOUND. The safe approach is to rely on framework-native aliases (like Next’s @/ convention), or ensure the same resolver is configured for TS and the runtime.
Mental model: TS resolves, runtime loads
When you write:
import { db } from "@/lib/db";You need two different systems to agree:
- TypeScript: “where is
@/lib/db?” - Runtime: “where is
@/lib/db?”
If only TS understands it, you get a build that type-checks but crashes when executed.
The TS config pieces
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}What this does
- Helps TS + editors resolve
@/x→./src/x.
What this does NOT do
- It does not transform emitted JavaScript.
- Node won’t magically start understanding
@/.
Safe setups by environment
1) Next.js (recommended for this repo)
Next.js already supports path aliases when configured, and it runs through its bundler.
Rule: keep paths aligned with your Next project root and avoid fancy multi-alias webs.
Example:
@/*→./or./src/*(pick one and stick to it)
2) Vite/Webpack (bundler apps)
You must configure alias in the bundler too.
- TS:
paths - Bundler:
resolve.alias
If these drift, you get “editor ok, runtime broken”.
3) Node scripts (no bundler)
If you execute TS/JS directly in Node (cron scripts, migrations):
- Either don’t use aliases (boring but reliable)
- Or use a runtime that supports TS path mapping (e.g. tsx/ts-node + path mapping support)
- Or compile with a build step that rewrites paths (bundler)
Production bias: for Node scripts, prefer relative imports.
Anti-patterns
Anti-pattern 1: Aliases across package boundaries
In monorepos, @/ can mean different roots. You end up with imports that compile in one package and break in another.
Anti-pattern 2: Aliases to dist/
Never alias to build output. It creates circular build assumptions.
Debugging playbook
If something fails in prod:
- Inspect the emitted JS: does it still contain
@/…? - Identify the runtime: Node? Next server? Edge runtime?
- Confirm the resolver that runtime uses supports aliases
Production rule of thumb
- If Node executes it (no bundler): avoid aliases.
- If a bundler executes it: configure aliases in exactly one place and keep TS in sync.
- Keep aliases minimal: one canonical alias beats five cute ones.
Interview questions
-
Q: What does
pathsdo in TypeScript?- A: It affects how TS resolves module specifiers for type-checking/tooling; it doesn’t rewrite runtime imports.
-
Q: Why do aliases sometimes work in dev but fail in prod?
- A: Dev bundler resolves aliases, but prod runtime path is different (or the build output still contains alias paths).
Quick recap
pathsis not a runtime feature.- Ensure bundler/runtime resolver matches TS.
- Prefer boring: one alias, consistent root, minimal magic.