@robonen/tsconfig
Shared, strict TypeScript configurations — a small set of layered presets you extend instead of copying compiler options between packages.
Every package in a monorepo wants the same modern, strict TypeScript baseline, but keeping a dozen tsconfig.json files in sync by hand drifts almost immediately. @robonen/tsconfig ships one carefully tuned base config and three environment layers — dom, vue, and node — that extend it. Point your package's extends at the right preset and you inherit a consistent, bundler-first, type-check-only setup with no local compiler options to maintain.
Layered presets
base → dom → vue, plus a sibling node layer. Extend the one that matches the environment; everything else is inherited.
Strict by default
strict plus noUncheckedIndexedAccess, noImplicitOverride, noImplicitReturns and noFallthroughCasesInSwitch are on out of the box.
Bundler-first
module: Preserve with Bundler resolution, verbatimModuleSyntax and isolatedModules. Emit is noEmit — declarations come from tsdown.
Env isolation
Browser src (DOM, no Node globals) and tooling files (node types, no DOM) split into separate projects wired with project references.
Install
Add the package as a dev dependency. It ships only JSON presets — no runtime code.
pnpm add -D @robonen/tsconfigUsage
Pick the preset that matches the package and extend it from your tsconfig.json:
// Node / isomorphic library
{ "extends": "@robonen/tsconfig/tsconfig.base.json" } Vue SFC packages extend the vue layer (adds jsx: preserve and strict vueCompilerOptions) and can declare path aliases inline:
// Vue package, with path aliases
{
"extends": "@robonen/tsconfig/tsconfig.vue.json",
"compilerOptions": {
"paths": { "@/*": ["./src/*"] }
}
}Note: path aliases resolve relative to the tsconfig.json location — baseUrl is intentionally omitted (deprecated, removed in TypeScript 7.0).
DOM + Node split
Most packages mix browser src with Node tooling files (vite.config.ts, vitest.config.ts, tsdown.config.ts). Split them into two projects wired with references so src never sees Node globals and config files never see DOM, then type-check the whole package with tsc -b / vue-tsc -b:
// tsconfig.json — solution root
{
"files": [],
"references": [
{ "path": "./tsconfig.src.json" }, // extends tsconfig.dom.json
{ "path": "./tsconfig.node.json" } // *.config.ts, types: ["node"]
]
}Where to next
- Presets — the full table of
base,dom,vueandnode, with what each layer adds. - Project references — the complete DOM + Node split with
compositeandtsBuildInfoFilewiring. - What's included — the exact compiler options the
basepreset turns on. - See the guide sections in the sidebar for each of the above.
@robonen/tsconfig
Shared TypeScript configurations.
Install
pnpm install -D @robonen/tsconfig
Presets
| Preset | Extends | Use for |
|---|---|---|
tsconfig.base.json |
— | Node / isomorphic libraries (lib: ESNext, no DOM) |
tsconfig.dom.json |
base | Browser libraries (adds DOM, DOM.Iterable) |
tsconfig.vue.json |
dom | Vue SFC libraries / apps (adds jsx, vueCompilerOptions) |
tsconfig.node.json |
base | Build/test tooling files (*.config.ts) — adds types: ["node"], no DOM |
tsconfig.json |
base | Default alias for base (bare @robonen/tsconfig import) |
Usage
Pick the preset that matches the package and extend it:
// Node / isomorphic library
{ "extends": "@robonen/tsconfig/tsconfig.base.json" }
// Browser library
{ "extends": "@robonen/tsconfig/tsconfig.dom.json" }
// Vue package, with path aliases
{
"extends": "@robonen/tsconfig/tsconfig.vue.json",
"compilerOptions": {
"paths": { "@/*": ["./src/*"] }
}
}
Path aliases resolve relative to the
tsconfig.jsonlocation —baseUrlis intentionally omitted (deprecated, removed in TypeScript 7.0).
Project references (DOM + Node split)
Most packages contain two environments: browser/library src (DOM) and Node
tooling files (vite.config.ts, vitest.config.ts, tsdown.config.ts). They
are split into separate projects wired with references, so src never sees Node
globals and config files never see DOM:
// tsconfig.json — solution root, tools (tsdown/vitest/editor) target src below
{
"files": [],
"references": [
{ "path": "./tsconfig.src.json" },
{ "path": "./tsconfig.node.json" }
]
}
// tsconfig.src.json — the library code
{
"extends": "@robonen/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"composite": true,
"types": [],
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.src.tsbuildinfo"
},
"include": ["src/**/*.ts"]
}
// tsconfig.node.json — build/test tooling files
{
"extends": "@robonen/tsconfig/tsconfig.node.json",
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo"
},
"include": ["*.config.ts"]
}
Type-check the whole package (both projects) with tsc -b / vue-tsc -b.
Point tsdown at the src project (tsconfig: './tsconfig.src.json') since the
root has no compilerOptions.
What's included (base)
- Target / Module:
ESNextwithmodule: Preserve+Bundlerresolution - Strict mode:
strict,noUncheckedIndexedAccess,noImplicitOverride,noImplicitReturns,noFallthroughCasesInSwitch,noUncheckedSideEffectImports - Module safety:
verbatimModuleSyntax,isolatedModules,moduleDetection: force - Type-check only:
noEmit(declarations/output are produced bytsdown) - Interop:
esModuleInterop,resolveJsonModule