Path aliases
ttsc is the standalone TypeScript-Go compiler โ see Setup if you havenโt installed it yet.
If your tsconfig.json uses compilerOptions.paths (e.g. @/* โ ./src/*), the emit will contain those alias paths verbatim โ and they wonโt resolve at runtime. @ttsc/paths rewrites them into relative imports during compile.
The problem
// src/main.ts (source)
import { value } from "@lib/value";After a plain ttsc build:
// dist/main.js (broken)
import { value } from "@lib/value"; // โ Node can't resolve thisThe fix
npm install -D @ttsc/paths// tsconfig.json
{
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"paths": {
"@/*": ["./src/*"],
"@lib/*": ["./src/modules/*"]
},
"plugins": [{ "transform": "@ttsc/paths" }]
}
}Now the emit is:
// dist/main.js
import { value } from "./modules/value.js";What it does and doesnโt do
- Reads the same
compilerOptions.paths,rootDir, andoutDirthatttscalready uses. - Rewrites both
.jsemit and.d.tsdeclarations. - No separate plugin config.
- Does not add
.jsextensions where they werenโt already implied โ NodeโsNodeNext/Bundlerresolution should match yourmodulesetting. - Does not change source files โ only the emit.
Common alternatives (and why this is simpler)
tsc-aliasโ post-build script. Works, but itโs a second pass.@ttsc/pathsruns inside the compile.- Path remapping at runtime via
tsconfig-paths/registerโ adds runtime cost and a startup step.@ttsc/pathsproduces normal relative imports. - Custom bundler config โ if a bundler owns your build, thatโs fine.
@ttsc/pathsis for projects that ship as plain Node packages.
Inspired by
typescript-transform-paths. Same goal, different compiler.
See also
- Plugins โ the plugin index.
- @ttsc/banner โ another emit-time plugin.
- Plugin Development โ write your own.
Last updated on