TypeScript Configuration Standardization
Standardized TypeScript configuration system for NexisChat monorepo
This guide explains the standardized TypeScript configuration system implemented across the NexisChat monorepo. The system provides consistent type checking rules while allowing package-specific customizations.
Overview
The TypeScript configuration system is built around a hierarchical inheritance model where all packages extend from standardized base configurations. This ensures consistency while maintaining flexibility for different project types.
Configuration Hierarchy
The configuration system is organized in the packages/typescript-config directory with the following structure:
packages/typescript-config/
├── base.json # Core base configuration
├── node.json # Node.js applications and packages
├── server.json # Server applications (Hono/Express)
├── nextjs.json # Next.js applications
├── astro.json # Astro applications
└── react-library.json # React libraries and componentsBase Configuration (base.json)
The base configuration provides core TypeScript settings that work across all project types:
- Target: ES2022 for modern JavaScript features
- Module System: ESNext with bundler resolution
- Strict Mode: Enabled for better type safety
- Isolated Modules: Enforced for better build performance
- Skip Lib Check: Enabled to improve compilation speed
- JSON Module Resolution: Enabled for importing JSON files
Key features:
- Consistent module resolution strategy
- Standardized library inclusions
- Unified strict mode settings
- Common path resolution patterns
- Isolated modules enforcement
Specialized Configurations
Server Configuration (server.json)
Used for Node.js server applications like apps/server, apps/evolution-api-lite, and apps/whatsapp-web-server.
Key Features:
- Extends base configuration
- Node.js module resolution
- JSX support for Hono applications
- Output directory configuration
- Server-side type definitions
When to use:
- Backend API servers
- Node.js applications with JSX
- Server-side rendering applications
Next.js Configuration (nextjs.json)
Used for Next.js applications like apps/docs and apps/subscription.
Key Features:
- Next.js plugin integration
- DOM and DOM.Iterable libraries
- JSX preserve mode
- No emit (Next.js handles compilation)
- Incremental compilation
When to use:
- Next.js applications
- React applications with SSR
- Documentation sites using Next.js
Astro Configuration (astro.json)
Used for Astro applications like apps/landing.
Key Features:
- Astro-specific settings
- Client-side libraries (DOM, DOM.Iterable)
- ESNext module system
- JSX preserve mode
- No emit configuration
When to use:
- Astro static site generators
- Multi-framework applications
- Content-focused websites
Node.js Configuration (node.json)
Used for Node.js packages and tools like packages/eslint-config.
Key Features:
- CommonJS module system
- Node.js module resolution
- Node.js type definitions
- Output directory configuration
- JavaScript support
When to use:
- Node.js libraries and tools
- CLI applications
- Build tools and utilities
Package Configuration Strategy
Each package in the monorepo extends from the appropriate specialized configuration:
| Package | Configuration | Rationale |
|---|---|---|
apps/client | react-library.json | React application with bundler |
apps/server | server.json | Hono server with JSX support |
apps/docs | nextjs.json | Next.js documentation site |
apps/subscription | nextjs.json | Next.js application |
apps/landing | astro.json | Astro static site |
apps/evolution-api-lite | node.json | Node.js API server |
apps/whatsapp-web-server | node.json | Node.js WebSocket server |
packages/ui | react-library.json | React component library |
packages/eslint-config | node.json | Node.js configuration package |
How to Extend Configurations
Basic Extension
To use a standardized configuration in your package:
{
"extends": "@repo/typescript-config/server.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}Package-Specific Overrides
You can override specific compiler options while maintaining inheritance:
{
"extends": "@repo/typescript-config/nextjs.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/components/*": ["./src/components/*"],
"@/lib/*": ["./src/lib/*"]
},
"plugins": [{ "name": "next" }, { "name": "@tailwindcss/typography" }]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"]
}Adding Custom Types
For packages that need additional type definitions:
{
"extends": "@repo/typescript-config/base.json",
"compilerOptions": {
"types": ["node", "jest", "@types/custom-library"]
}
}Inheritance Hierarchy
The configuration inheritance follows this pattern:
base.json (Core settings)
↓
specialized-config.json (Project-type specific)
↓
package/tsconfig.json (Package-specific overrides)What Gets Inherited
- Compiler Options: All base compiler options are inherited
- Library Inclusions: Base libraries plus specialized additions
- Strict Mode Settings: Consistent across all packages
- Module Resolution: Standardized resolution strategy
What Can Be Overridden
- Include/Exclude Patterns: Package-specific file patterns
- Path Mappings: Internal import aliases
- Output Directory: Build output location
- Additional Types: Package-specific type definitions
- Plugins: Framework-specific plugins
Troubleshooting Guide
Common Issues and Solutions
1. Module Resolution Errors
Problem: Cannot find module or type definitions
Solution: Check if the correct base configuration is being used:
{
"extends": "@repo/typescript-config/node.json", // For Node.js packages
"compilerOptions": {
"moduleResolution": "node" // Inherited from node.json
}
}2. JSX Compilation Issues
Problem: JSX syntax not recognized or compiled incorrectly
Solution: Use the appropriate configuration for your JSX needs:
- React JSX: Use
server.json(setsjsx: "react-jsx") - Preserve JSX: Use
nextjs.jsonorastro.json(setsjsx: "preserve")
3. Type Checking Isolation Problems
Problem: Types from other packages causing conflicts
Solution: Ensure proper include/exclude patterns:
{
"include": ["src/**/*", "types/**/*"],
"exclude": ["node_modules", "dist", "../**/src"] // Exclude sibling packages
}4. Build Output Issues
Problem: Compiled files in wrong location or format
Solution: Check output configuration:
{
"extends": "@repo/typescript-config/node.json",
"compilerOptions": {
"outDir": "./dist", // Customize output directory
"noEmit": false // Ensure compilation is enabled
}
}5. Library and Types Not Found
Problem: Cannot find DOM types or Node.js types
Solution: Verify the correct specialized configuration:
// For client-side code
{
"extends": "@repo/typescript-config/nextjs.json", // Includes DOM libraries
}
// For server-side code
{
"extends": "@repo/typescript-config/server.json", // Includes Node.js types
}Debugging Configuration Issues
1. Check Configuration Resolution
Use TypeScript's --showConfig flag to see the resolved configuration:
npx tsc --showConfig2. Validate Configuration Syntax
Ensure your tsconfig.json is valid JSON:
npx tsc --noEmit --project ./tsconfig.json3. Test Type Checking
Run type checking for a specific package:
cd apps/your-package
pnpm typecheck4. Check Inheritance Chain
Verify that the base configuration is being found:
# From package directory
ls -la node_modules/@repo/typescript-config/Performance Optimization
1. Skip Library Checking
The base configuration includes skipLibCheck: true to improve compilation speed. This is generally safe for most projects.
2. Incremental Compilation
For development, enable incremental compilation:
{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": ".tsbuildinfo"
}
}3. Project References
For large monorepos, consider using TypeScript project references:
{
"references": [{ "path": "../shared-package" }]
}Best Practices
1. Minimal Overrides
Only override settings that are absolutely necessary for your package:
// Good: Minimal, necessary overrides
{
"extends": "@repo/typescript-config/nextjs.json",
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
}
}
// Avoid: Duplicating inherited settings
{
"extends": "@repo/typescript-config/nextjs.json",
"compilerOptions": {
"strict": true, // Already inherited
"skipLibCheck": true, // Already inherited
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
}
}2. Consistent File Patterns
Use consistent include/exclude patterns across similar packages:
{
"include": ["src/**/*", "types/**/*", "*.config.*"],
"exclude": ["node_modules", "dist", "build", ".next"]
}3. Environment-Specific Configurations
For packages that need different settings for different environments:
// tsconfig.json (development)
{
"extends": "@repo/typescript-config/server.json",
"compilerOptions": {
"sourceMap": true
}
}
// tsconfig.build.json (production)
{
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"removeComments": true
},
"exclude": ["**/*.test.ts", "**/*.spec.ts"]
}4. Type-Only Imports
Use type-only imports to prevent runtime dependencies:
import type { SomeType } from '@repo/shared-types'
import { someFunction } from '@repo/shared-utils'Migration Guide
Migrating Existing Packages
- Identify Current Configuration: Check your current
tsconfig.json - Choose Appropriate Base: Select the right specialized configuration
- Update Extends: Change to extend from the standardized config
- Remove Redundant Options: Remove settings that are now inherited
- Test Type Checking: Verify that everything still works
Example Migration
Before:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"strict": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"outDir": "dist",
"jsx": "react-jsx",
"types": ["node"]
}
}After:
{
"extends": "@repo/typescript-config/server.json",
"compilerOptions": {
"baseUrl": "."
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}Maintenance
Adding New Configurations
When adding new project types:
- Create a new specialized configuration in
packages/typescript-config - Extend from
base.json - Add project-specific compiler options
- Update this documentation
- Test with a sample project
Updating Base Configuration
When updating the base configuration:
- Consider impact on all packages
- Test changes across different project types
- Update specialized configurations if needed
- Communicate changes to the team
- Update documentation
Configuration Validation
The CI system validates TypeScript configurations:
# Run validation across all packages
pnpm ci:validate
# Check specific package
cd apps/your-package && pnpm typecheckThis ensures that all packages maintain consistent and working TypeScript configurations.