TypeScript
Shared TypeScript configurations with @zeno-lib/typescript
Zeno uses the @zeno-lib/typescript package to share strict TypeScript configurations across all packages and apps.
You don't have to set tsconfig.json options such as moduleResolution, jsx, lib, strict, Next.js include globs or the Next.js plugin by hand. Extend one config and it sets them for you.
Available configs
The configs form an inheritance chain. Each level extends the previous one:
| Config | Extends | Purpose |
|---|---|---|
base.json | None | Core settings (module resolution, ESNext, bundler mode, JSON imports) |
strict.json | base | Enables strict: true |
strictest.json | strict | Extra strict checks (no unused locals or parameters, no switch fallthrough, no unchecked indexed access) |
react.json | strictest | Adds JSX support and DOM lib |
nextjs.json | react | Adds Next.js plugin, next-env.d.ts, and .next/types includes |
Usage
Extend the appropriate config in your package's tsconfig.json:
{
"extends": "@zeno-lib/typescript/nextjs.json"
}You don't need to set compilerOptions, include or exclude. The config handles module resolution, strict checks, JSX, the DOM libs and the Next.js includes.
Which config to use
| Package type | Config |
|---|---|
| Next.js app | @zeno-lib/typescript/nextjs.json |
| React library | @zeno-lib/typescript/react.json |
| Non-React package | @zeno-lib/typescript/strictest.json |
| Loose / legacy | @zeno-lib/typescript/strict.json |
Examples in the repo
| Package | Config |
|---|---|
apps/docs | @zeno-lib/typescript/nextjs.json |
packages/ui | @zeno-lib/typescript/react.json |
packages/supabase | @zeno-lib/typescript/strictest.json |
packages/e2e | @zeno-lib/typescript/strictest.json |
What's included
Base config
Every config inherits these settings:
- Bundler module resolution: resolves imports the way bundlers such as Vite, Turbopack and webpack do
- ESNext modules with
verbatimModuleSyntax: TypeScript drops imports markedtypeand leaves every other import and export as written - JSON imports:
resolveJsonModuleis on - Incremental builds: TypeScript reuses the previous run's results, so rechecks are faster
- Isolated modules: every file must compile on its own, as SWC and esbuild require
- No emit: TypeScript only type-checks, and bundlers produce the output
Strictest config
Adds these checks on top of strict: true:
noFallthroughCasesInSwitch: prevents fallthrough in switch statementsnoImplicitOverride: requires theoverridekeywordnoImplicitReturns: every code path must returnnoUnusedLocals: no unused local variablesnoUnusedParameters: no unused function parametersnoUncheckedIndexedAccess: indexed access returnsT | undefinedallowUnreachableCode: false: unreachable code is an errorallowUnusedLabels: false: unused labels are an error
Next.js config
On top of the React config, the Next.js config:
- Registers the
nextTypeScript plugin for App Router type safety - Includes
next-env.d.tsand.next/types/**/*.tsfor generated types - Includes every
*.tsand*.tsxfile under the project root
Type checking
Run type checking across all packages:
pnpm types:checkOr for a specific package:
pnpm turbo run types:check --filter @zeno-lib/ui