This repository contains the baseline TypeScript compiler configuration for all Bedrock projects that use TypeScript 5 or newer. It is verified against TypeScript 5.x, 6.x, and 7.x.
Two configurations are published:
| Entry point | For |
|---|---|
@bdrk/typescript-config |
Node.js services and libraries compiled with tsc |
@bdrk/typescript-config/react |
React applications built with a bundler (Vite, Next, …) |
You can reference this config by installing the NPM package in your project:
npm install --save-dev @bdrk/typescript-configThen replace the contents of your tsconfig.json file with:
{
"extends": "@bdrk/typescript-config",
"include": ["./src/**/*"]
}You can overwrite settings defined in this configuration by specifying them in your project's tsconfig.json.
This configuration targets Node.js projects with the conventional layout of sources in src/
compiled to dist/:
target: ES2022/lib: ["ES2022"]— safe for all maintained Node.js releasesmodule: nodenext/moduleResolution: nodenext— modern Node.js module semantics (emits CommonJS unless yourpackage.jsondeclares"type": "module")rootDir: src/outDir: dist— resolved relative to your project root; TypeScript 6+ requires an explicitrootDir, so override it if your sources live elsewhereresolveJsonModule,esModuleInterop, andskipLibCheckare enabledstrictNullChecksis enabled (fullstrictmode is not)
React applications should extend the react entry point instead:
{
"extends": "@bdrk/typescript-config/react",
"include": ["./src/**/*"]
}It builds on the base configuration and changes the following:
jsx: react-jsx— the React 17+ automatic runtime, so.tsxfiles compile without importingReactinto scopelib: ["DOM", "DOM.Iterable", "ES2022"]— required by@types/react-dommodule: esnext/moduleResolution: bundler— matches how bundlers actually resolve imports, and drops thenodenextrequirement that relative imports carry a.jsextensionisolatedModulesandverbatimModuleSyntax— enforce what single-file transpilers (esbuild, SWC, Babel) can safely handle, so type-only imports and re-exports must sayimport type/export typemoduleDetection: force— every file is a module, so top-level names in files without imports don't collide in the global scopestrict: true— the full strict family rather than the base'sstrictNullChecksalone. In React this mainly buysnoImplicitAnyon props, event handlers, anduseRefinitializers, plus stricter checking of callback propstypes: []— no ambient type packages are loaded by default, so browser code doesn't pick up Node.js globals (for example,setTimeoutreturningNodeJS.Timeout)noEmit: trueanddeclaration: false— the bundler produces the output;tsconly type-checks
rootDir and outDir are inherited from the base configuration and remain pointed at
src/ and dist/. rootDir is still enforced under noEmit, so override it if your
sources live elsewhere.
Because types is empty, add whatever ambient packages your toolchain needs. For Vite,
this is what makes import.meta.env and asset imports type-check:
{
"extends": "@bdrk/typescript-config/react",
"compilerOptions": {
"types": ["vite/client"]
}
}Other common entries are ["node"] for Next.js projects with server-side code, and
["@testing-library/jest-dom"] for test configurations.
The react entry point assumes a bundler owns the build. If you are publishing a React
component library compiled with tsc, re-enable declaration output:
{
"extends": "@bdrk/typescript-config/react",
"compilerOptions": {
"noEmit": false,
"declaration": true,
"declarationMap": true
}
}Non-React browser projects should add the DOM libraries:
{
"extends": "@bdrk/typescript-config",
"compilerOptions": {
"lib": ["DOM", "ES2022"]
}
}Projects using legacy (pre-TC39) decorators, such as NestJS or TypeORM services, should set:
{
"extends": "@bdrk/typescript-config",
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}