# Key Compiler Options Used in Open-SEO's tsconfig.json

> Discover essential tsconfig.json compiler options in Open-SEO. Learn about ESNext modules, React JSX, path aliasing, and Vite integration for a modern TypeScript setup.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: internals
- Published: 2026-08-08

---

**Open-SEO's [`tsconfig.json`](https://github.com/every-app/open-seo/blob/main/tsconfig.json) configures a strict, modern TypeScript environment with ESNext modules, React JSX transform, path aliasing via `@`, and a no-emit architecture that delegates compilation to Vite.**

The Open-SEO repository relies on a meticulously configured TypeScript setup to power its SEO management platform. Located at the repository root, the [`tsconfig.json`](https://github.com/every-app/open-seo/blob/main/tsconfig.json) file governs type checking across the entire codebase, from server-side functions to React frontend components. These compiler options establish a strict development environment while optimizing for fast builds and seamless interoperability with modern bundlers.

## Strict Type Checking and Modern JavaScript

### Enforcing Strict Type Safety

The configuration enables `strict: true`, which activates all strict type-checking flags including `noImplicitAny` and `strictNullChecks`. This guarantees type safety across the large codebase, preventing subtle bugs in server functions and UI components. The `target` is set to `ES2022`, emitting JavaScript that matches the modern Node 18+ and browser runtime environments while enabling newer syntax features.

### Platform-Consistent File Naming

To prevent bugs on case-sensitive filesystems (Linux/CI) while allowing case-insensitive development on macOS and Windows, the configuration sets `forceConsistentCasingInFileNames: true`. This ensures that imports like `import { helper } from './Utils'` will fail if the actual filename is [`utils.ts`](https://github.com/every-app/open-seo/blob/main/utils.ts), catching potential cross-platform issues early.

## Module Resolution and Interoperability

### ESNext Module System

Open-SEO uses `module: ESNext` to generate native ES module syntax (`import`/`export`), which aligns with the Vite bundler's expectations and enables tree-shaking for smaller bundle sizes. The `moduleResolution: Bundler` setting ensures TypeScript resolves modules the same way Vite does, avoiding "module not found" mismatches between the type checker and the runtime bundler.

### Seamless Library Integration

The `esModuleInterop: true` flag enables default-import interoperability for CommonJS modules, allowing ES-style imports like `import express from 'express'` rather than namespace imports. Additionally, `allowJs: true` permits the inclusion of plain `.js` files in the compilation, letting legacy scripts and third-party utilities coexist with TypeScript code.

### JSON and Extension Handling

With `resolveJsonModule: true`, the project can import JSON files directly as modules for static configuration files such as feature flags. The `allowImportingTsExtensions: true` option supports explicit file-extension imports (e.g., `import { calc } from './utils.ts'`), which provides clarity in the monorepo structure.

## React JSX and Frontend Configuration

### Modern JSX Transform

For the React components located in `web/src/`, the configuration specifies `jsx: react-jsx`, which uses the new JSX transform introduced in React 17+. This allows components to be written without explicit `React.createElement` imports, reducing boilerplate. The `lib` array includes `["DOM", "DOM.Iterable", "ES2023"]`, providing full type definitions for browser APIs and the latest ECMAScript features for frontend code.

## Path Mapping and Import Aliases

### Simplified Imports with `@` Alias

The `paths` compiler option maps `@/*` to `./src/*`, creating a clean path alias that simplifies imports throughout the codebase:

```typescript
import { getProject } from '@/serverFunctions/projects';
import seoDefaults from '@/config/seo-defaults.json';

```

This improves readability and makes refactoring easier, as moving files does not require updating relative path traversals (`../../`).

## Build Optimization and No-Emit Architecture

### Delegating Compilation to Vite

Open-SEO sets `noEmit: true`, instructing TypeScript not to generate output files. The actual JavaScript production is handled by Vite, while TypeScript's role remains purely type-checking. This separation of concerns speeds up the development feedback loop.

### Isolated Compilation and Performance

The `isolatedModules: true` flag ensures each file can be safely transpiled in isolation, which is essential when Babel or Vite processes files individually. Combined with `skipLibCheck: true`—which skips type checking of declaration files (`*.d.ts`)—the configuration maintains fast compilation times while still thoroughly type-checking the project's own source code.

## Project Scoping with Include and Exclude

The `include` pattern `["**/*.ts", "**/*.tsx"]` ensures every TypeScript source file is covered, including server functions and UI components. Conversely, the `exclude` array `["web/**/*", "badseo/**/*"]` removes specific directories from type-checking:

- `web/**/*` contains the Vite-powered frontend, which may have its own TypeScript configuration
- `badseo/**/*` holds experimental code that should not affect the main build stability

## Summary

- **`strict: true`** enforces comprehensive type safety across the entire Open-SEO codebase
- **`module: ESNext`** with **`moduleResolution: Bundler`** aligns TypeScript resolution with Vite's behavior
- **`jsx: react-jsx`** enables the modern React 17+ transform for components in `web/src/`
- **`paths: {"@/*": ["./src/*"]}`** creates intuitive import aliases that improve code maintainability
- **`noEmit: true`** establishes a fast no-emit architecture where TypeScript handles type-checking only
- **`exclude`** patterns isolate the `web` and `badseo` directories from the main compilation scope

## Frequently Asked Questions

### Why does Open-SEO use `noEmit: true` in tsconfig.json?

Open-SEO delegates JavaScript emission to Vite rather than the TypeScript compiler. Setting `noEmit: true` allows TypeScript to focus exclusively on type-checking during development, significantly improving build speeds while the bundler handles the actual transpilation and optimization of the output code.

### How does the `@` path alias work in the Open-SEO project?

The `paths` configuration maps `@/*` to `./src/*`, enabling developers to write imports like `import { helper } from '@/utils/helper'` instead of relative paths like `../../../utils/helper`. This alias is resolved by TypeScript during type-checking and must be configured in the bundler (Vite) as well for runtime resolution.

### What is the purpose of `moduleResolution: Bundler` in this configuration?

This setting ensures that TypeScript resolves modules using the same logic as modern bundlers like Vite or Webpack. It supports features such as extensionless imports and proper handling of package.json exports, preventing discrepancies where TypeScript might fail to find a module that the bundler can resolve correctly.

### Why are the `web` and `badseo` folders excluded from type-checking?

The `web` directory contains the Vite-powered frontend that typically maintains its own TypeScript configuration separate from the server-side code. The `badseo` folder contains experimental or legacy code that should not trigger type errors in the main build pipeline, keeping the CI/CD process stable while allowing experimental development to proceed in isolation.