---
title: TypeScript Config
description: The shared compiler options, and the alias everything resolves through.
type: reference
related:
- /en/docs/structure
- /en/docs/packages/testing
---
# TypeScript Config
Three configs, extended by every app and package:
```json title="apps/app/tsconfig.json"
{
"extends": "@kreogen/typescript-config/nextjs.json"
}
```
| Config | For |
| -------------------- | -------------------------------------------------- |
| `base.json` | Everything. Strict, ES2022, NodeNext |
| `nextjs.json` | Apps and any package importing React in a Next app |
| `react-library.json` | A React library compiled outside Next |
## The alias
`nextjs.json` is where `@kreogen/*` becomes resolvable:
```json
"paths": {
"@/*": ["./*"],
"@kreogen/*": ["../../packages/*"]
}
```
That single line is why packages need no `exports` map and no build step:
`@kreogen/auth/session` resolves directly to `packages/auth/session.ts`.
This path is written relative to an app directory, two levels below the
workspace root. It is duplicated in `@kreogen/testing`, which every test run
reads, and the two must agree — a test fails when they drift, because nothing
else would tell you. TypeScript reports a missing module and explains nothing
about why.
The consequence is worth restating: **renaming a file in a package is a
breaking API change.** There is no indirection between the import specifier and
the file on disk.
## Strictness worth knowing about
Beyond `strict: true`, four options are on that many projects leave off:
**`noUncheckedIndexedAccess`.** `array[0]` is `T | undefined`, and
`record[key]` likewise. This is the one that produces the most friction and
prevents the most bugs — a `Record` is typed as total but is
not, so an index that misses yields `undefined` and arithmetic on it silently
produces `NaN`. That exact failure reached a rate limiter's window calculation
here before this was enabled.
**`noUnusedLocals` and `noUnusedParameters`.** A dead variable is usually the
residue of a half-finished edit. Prefix a genuinely unused parameter with `_`.
**`noFallthroughCasesInSwitch`.** Fallthrough is almost always a missing
`break`, and webhook handlers are full of switches.
**`isolatedModules`.** Each file must be transpilable alone, which is what
bundlers actually do. It forces `import type` for type-only imports — annoying
until the first time a type import fails to be erased and drags a whole module
into a client bundle.
## Typecheck
```sh
bun run typecheck
```
Every app and package runs `tsc --noEmit`. In turbo this depends on `^build`,
because packages need the generated Prisma client before they will typecheck at
all — and `@kreogen/database` additionally depends on its own build, since it
generates that client.
The apps set `noEmit: true` and `declaration: false`: Next does the compiling,
and `tsc` is only ever asked whether the code is correct.
---
For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)
For an index of all available documentation, see [/llms.txt](/llms.txt)