# What Is the Purpose of the Types Folder in Open‑SEO?

> Discover the purpose of the types folder in Open-SEO. It houses TypeScript contracts and Zod schemas for compile-time safety and consistent API contracts across the application.

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

---

**The `src/types` directory serves as the central hub for TypeScript type contracts and Zod runtime validation schemas, ensuring compile-time safety and consistent API contracts across the entire Open‑SEO application.**

The Open‑SEO repository relies on strict type safety to manage complex data flows between frontend components, server functions, and database layers. Located at `src/types`, this folder acts as the single source of truth for all data structures, coupling static TypeScript definitions with runtime Zod validation to prevent errors before they reach production.

## Core Responsibilities of the Types Folder

The types folder fulfills three critical architectural needs: defining data shapes for the TypeScript compiler, validating untrusted runtime inputs, and maintaining modular organization across feature boundaries.

### Static Type Definitions for Compile-Time Safety

Top-level files like [`src/types/keywords.ts`](https://github.com/every-app/open-seo/blob/main/src/types/keywords.ts) export interfaces that describe the exact shape of data flowing through the application. These definitions cover **project payloads**, **keyword records**, **rank-tracking results**, and **search-performance filters**. By importing these types into frontend components, API routes, and database services, Open‑SEO ensures that refactoring a data structure propagates type errors to every dependent location immediately.

### Runtime Validation with Zod Schemas

The `src/types/schemas` subfolder contains Zod schemas (e.g., `createProjectSchema`, `searchPerformanceInputSchema`) that validate incoming API requests and form data. Each schema exports a corresponding TypeScript type derived via `z.infer<typeof schema>`, creating a tight coupling between runtime checks and static analysis. This pattern guarantees that data passing validation is automatically typed, eliminating the risk of runtime type mismatches.

### Modular Organization for Reusability

The folder structure separates concerns by placing Zod schemas in `src/types/schemas/` while keeping domain-specific interfaces at the top level. This separation allows services, routes, and test suites to import exactly what they need—whether pure types for frontend props or full schemas for backend validation—without creating circular dependencies.

## Practical Implementation Examples

The following patterns demonstrate how Open‑SEO leverages the types folder across different layers of the stack.

### Validating API Requests in Route Handlers

When creating a new project, the handler uses `createProjectSchema` from [`src/types/schemas/projects.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/projects.ts) to validate the request body before processing:

```typescript
import { createProjectSchema, type CreateProjectInput } from '@/types/schemas/projects';

// Express-like handler
export async function createProjectHandler(req, res) {
  const parsed = createProjectSchema.safeParse(req.body);
  if (!parsed.success) {
    return res.status(400).json({ errors: parsed.error.format() });
  }

  // `parsed.data` is typed as `CreateProjectInput`
  const input: CreateProjectInput = parsed.data;
  // …logic that stores the project…
}

```

### Type-Safe Frontend Components

React components import interfaces directly from the types folder to enforce prop contracts. The `KeywordResearchRow` type from [`src/types/keywords.ts`](https://github.com/every-app/open-seo/blob/main/src/types/keywords.ts) ensures UI elements handle nullable fields correctly:

```typescript
import type { KeywordResearchRow } from '@/types/keywords';

function KeywordRow({ row }: { row: KeywordResearchRow }) {
  return (
    <div>
      <h3>{row.keyword}</h3>
      <p>Search volume: {row.searchVolume ?? '—'}</p>
      <p>Intent: {row.intent}</p>
    </div>
  );
}

```

### Query Parameter Validation

For search performance filtering, the application validates query strings against `searchPerformanceInputSchema` defined in [`src/types/schemas/search-performance.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/search-performance.ts):

```typescript
import { searchPerformanceInputSchema } from '@/types/schemas/search-performance';

export function getSearchPerformance(req) {
  const result = searchPerformanceInputSchema.parse(req.query);
  // `result` now has a strongly-typed shape:
  // { projectId: string; dateRange: SearchPerformanceDateRange; device?: SearchPerformanceDevice; country?: string }
  // …fetch data from GSC using these filters…
}

```

### Rank Tracking Data Structures

The rank-tracking feature relies on types exported from [`src/types/schemas/rank-tracking.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/rank-tracking.ts) to maintain consistent data shapes across device types:

```typescript
import type { RankTrackingRow } from '@/types/schemas/rank-tracking';

function renderRankRow(row: RankTrackingRow) {
  // `row.desktop` and `row.mobile` follow the `RankTrackingDeviceResult` interface
}

```

## Key Files in the Types Directory

Understanding the specific files within `src/types` clarifies how data contracts are maintained:

- **[`src/types/schemas/projects.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/projects.ts)** – Contains Zod schemas and TypeScript types for creating, updating, and managing SEO projects, including `createProjectSchema` and `CreateProjectInput`.

- **[`src/types/keywords.ts`](https://github.com/every-app/open-seo/blob/main/src/types/keywords.ts)** – Defines core keyword-related interfaces such as `KeywordResearchRow` and `SavedKeywordRow`, used by both the research UI and database layer.

- **[`src/types/schemas/search-performance.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/search-performance.ts)** – Houses validation schemas and enums for Google Search Console integration, including filters for date ranges, devices, and geographic regions.

- **[`src/types/schemas/rank-tracking.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/rank-tracking.ts)** – Exports types and schemas used by the rank-tracking feature, covering configuration objects, result rows, and historical data points.

## Summary

- The `src/types` folder is the **single source of truth** for all data structures in Open‑SEO, consumed by frontend, backend, and database layers.
- **Zod schemas** provide runtime validation while exporting TypeScript types via `z.infer`, ensuring safety at both compile time and execution time.
- The **modular folder structure** separates pure type definitions from validation logic, preventing circular dependencies and improving code discoverability.
- Critical paths include [`src/types/schemas/projects.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/projects.ts) for project management and [`src/types/keywords.ts`](https://github.com/every-app/open-seo/blob/main/src/types/keywords.ts) for keyword research workflows.

## Frequently Asked Questions

### What is the difference between the schemas subfolder and top-level type files?

The `src/types/schemas/` directory specifically contains Zod validation objects and their inferred types, handling runtime safety for API inputs. Top-level files like [`src/types/keywords.ts`](https://github.com/every-app/open-seo/blob/main/src/types/keywords.ts) contain pure TypeScript interfaces used for component props and internal data modeling without validation overhead. This separation allows developers to import lightweight types for UI work while reserving heavy validation logic for API boundaries.

### How does Open‑SEO ensure type safety at runtime?

Open‑SEO couples Zod schemas with TypeScript through the `z.infer` utility. When `createProjectSchema.safeParse()` validates a request in [`src/types/schemas/projects.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/projects.ts), the resulting `parsed.data` object automatically receives the `CreateProjectInput` type. This pattern ensures that any data passing validation is guaranteed to match the TypeScript contract, preventing runtime exceptions from malformed payloads.

### Can I extend these types for custom Open‑SEO integrations?

Yes. Because the types folder exports both schemas and standalone interfaces, external integrations can import base types like `KeywordResearchRow` or `RankTrackingRow` to build compatible data structures. When extending, maintain the Zod schema alongside any new TypeScript interface to preserve the library's validation guarantees across API boundaries.

### Where are project-specific validation rules defined?

Project-specific rules reside in [`src/types/schemas/projects.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/projects.ts). This file exports `createProjectSchema` for initial project creation and update schemas for modification operations, centralizing all project-related validation logic. By keeping these rules in the types folder rather than route handlers, Open‑SEO ensures consistent validation whether projects are created via the REST API, internal services, or background jobs.