Application-wide source aliases
A large application wants stable imports such as @app/* instead of long relative paths.
TypeScript · Const
The paths compiler option maps import names or prefixes to lookup locations for TypeScript module resolution. It helps the compiler understand aliases, but does not rewrite emitted imports or configure runtime resolution.
In tsconfig.json, paths maps import prefixes or exact names to one or more lookup patterns. Resolution is relative to baseUrl when it is set, otherwise to the tsconfig file, and the mapping is used by TypeScript for resolving imports rather than rewriting emitted module paths.
{
"compilerOptions": {
"paths": {
"alias/*": ["replacement/*"]
}
}
}| Name | Type | Description |
|---|---|---|
paths | Record<string, string[]> | Object whose keys are import names or wildcard prefixes and whose values are arrays of replacement lookup patterns. |
No runtime value; this is a tsconfig compiler option that influences module resolution.
// tsconfig.json
{
"compilerOptions": {
"module": "NodeNext",
"paths": {
"@app/*": ["./src/app/*"]
}
}
}
// src/app/config.ts
export const port = 3000;
// src/main.ts
import { port } from "@app/config";
console.log(port);The alias lets TypeScript resolve the import to src/app/config.ts during type checking; configure the runtime or bundler with the same mapping.
A large application wants stable imports such as @app/* instead of long relative paths.
A project needs TypeScript to resolve a vendor package name to a checked-in local file.
A monorepo uses consistent source prefixes while a bundler supplies the corresponding runtime aliases.
The paths option declares custom import-resolution mappings. Its keys can represent an import name or prefix, and the values are lookup locations resolved relative to baseUrl when present, otherwise relative to tsconfig.json.
Follow-up: Does paths make Node.js understand the alias? No. The page explicitly says emitted import paths are unchanged, so the runtime or bundler needs its own mapping.
Each mapping associates an import pattern with one or more target patterns. For example, app/* can map to ./src/app/*, allowing imports such as app/config to be checked against src/app/config.
Follow-up: Why might multiple targets be useful? They provide fallback lookup locations when the first target does not resolve.
When baseUrl is set, path targets are interpreted relative to that directory. Without baseUrl, they are interpreted relative to the tsconfig file itself; since TypeScript 4.1, baseUrl is not required for paths.
Follow-up: What must be configured outside TypeScript? The tool that loads or bundles the code must reproduce the mapping because tsc does not rewrite these imports.
baseUrlmoduleResolutiontsconfig.json