tsconfig.json marks a project root: compilerOptions sets checking and output, include lists the source folders, and extends inherits a shared base (an array of bases since TypeScript 5.0). npx tsc --init writes a short starter file; npx tsc --showConfig prints the final merged settings, including implied ones.
Recommended settings
strict and target can stay at their TypeScript 6.0 defaults (The Basics). The app column follows the create-vite templates; the library column emits JavaScript and .d.ts files for npm 2,036 .
| Option | Vite 25,978 app | Library |
|---|---|---|
| module / moduleResolution | esnext / bundler | nodenext (implied) |
| Output | noEmit: true (Vite emits) | outDir: "dist", rootDir: "src" |
| .d.ts files | Not needed | declaration, declarationMap, isolatedDeclarations |
| types | ["vite/client"] | ["node"] if used |
| Other flags | verbatimModuleSyntax, erasableSyntaxOnly, skipLibCheck | Same, plus noUncheckedIndexedAccess |
isolatedDeclarations requires explicit types on exports, so other tools can write .d.ts files one file at a time. export function first(items: string[]) { return items[0]; } fails with error TS9013: Expression type can't be inferred with --isolatedDeclarations; add : string | undefined and tsc emits the declaration.
The tsc CLI and watch mode
tsc builds the nearest tsconfig.json; -p <path> picks another, --noEmit only checks, -w rechecks on every save and -b builds project references. Passing file names while a tsconfig.json exists is error TS5112 since 6.0 (add --ignoreConfig). TypeScript 7.0 adds --checkers and --builders to tune its threads (TypeScript 6 and 7).
Project references
Split a large repository into projects with "composite": true, then list dependencies in "references". tsc -b builds them in order, writes a .tsbuildinfo file per project and skips projects whose inputs are unchanged:
{
"compilerOptions": { "module": "nodenext", "outDir": "dist", "rootDir": "src" },
"references": [{ "path": "../core" }]
}$ npx tsc -b app --verbose Project 'core/tsconfig.json' is up to date because newest input 'core/src/index.ts' is older than output 'core/tsconfig.tsbuildinfo' Project 'app/tsconfig.json' is up to date because newest input 'app/src/main.ts' is older than output 'app/dist/main.js'
Build-tool integration
Vite 8, esbuild 126 , tsx 12,162 and Node.js 2,131 strip types one file at a time and never type-check, which is why isolatedModules matters. Keep tsc in the loop: the Vite template's build script is tsc -b && vite build, and vite-plugin-checker 1,239 (https://github.com/fi3ework/vite-plugin-checker 1,239 ) runs tsc in a separate process and shows errors in the browser. For libraries, tsdown 4,285 (https://github.com/rolldown/tsdown 4,285 ) bundles JavaScript and declarations with Rolldown 181,166 .