Open-SEO Backend Directory Structure: Complete Guide to the TypeScript Monorepo Layout

The open-seo backend directory structure organizes code as a modular TypeScript monorepo where src/ contains distinct directories for TanStack server functions, workflow orchestration, database schemas supporting both D1 (SQLite) and PostgreSQL, API routes, and shared business logic.

The open-seo backend follows a production-grade architecture designed for SEO automation workflows and multi-database flexibility. As implemented in every-app/open-seo, the repository cleanly separates workflow orchestration from API surface definitions while maintaining type safety through Zod schemas. Understanding this layout is essential for developers extending the platform or deploying self-hosted instances.

Core Application Architecture

The src/ directory houses all backend application code and serves as the primary development root. Within this folder, six functional domains manage distinct responsibilities: server orchestration, API functions, database abstraction, shared utilities, type definitions, and request middleware.

Server Functions and Workflow Orchestration

The src/server/ directory contains TanStack Server infrastructure and workflow orchestrators that power complex background jobs. Multi-step operations like site audits and rank checking reside in src/server/workflows/, where execution is coordinated through discrete phases.

API Routes and Middleware

HTTP path definitions live in src/routes/, mapping endpoints to the underlying server functions. The src/middleware/ directory provides Express-style pipeline components for cross-cutting concerns like authentication.

Database Layer and Schema Management

The backend supports dual database targets through a clean abstraction layer. The src/db/ directory contains database-agnostic Drizzle ORM schema definitions, with platform-specific implementations isolated in environment-specific subdirectories.

Schema and Client Implementations

  • src/db/schema.ts – Drizzle schema definitions for the SQLite/D1 backend covering core entities
  • src/db/pg/schema.ts – PostgreSQL-specific schema extensions for advanced indexing
  • src/db/pg/client.ts – PostgreSQL connection pool and query interface using the pg library
  • src/db/d1/client.ts – D1 (Cloudflare SQLite) specific client implementation for serverless deployments

Migration Management

Database migrations are versioned separately by target to prevent conflicts:

Shared Utilities and Type Safety

Reusable business logic resides in src/shared/, including Google Search Console integration (src/shared/gsc.ts), billing calculations, and keyword processing helpers. Core libraries for authentication and session management live in src/lib/, with src/lib/auth.ts handling environment pre-flight checks.

Type safety is enforced through Zod schemas located in src/types/. The file src/types/schemas/projects.ts defines API payload validations and internal data structures that are shared across the monorepo.

Testing and Operational Support

The repository root contains infrastructure for quality assurance and deployment:

  • e2e/ – Playwright end-to-end test suite exercising critical backend API flows, such as keyword-research-navigation.spec.ts
  • scripts/ – Utility scripts for seeding data, running migrations, and deployment pre-flight checks (e.g., scripts/seed-projects.ts)
  • docs/ – Developer documentation and self-hosting guides including SELF_HOSTING_DOCKER.md
  • runbooks/ – Operational guides for database migrations and troubleshooting production issues

Code Implementation Examples

The following snippets demonstrate how directory components integrate in practice.

Defining a TanStack Server Function

Server functions in src/serverFunctions/ wrap business logic for client exposure:

// src/serverFunctions/searchPerformance.ts
import { defineServerFunction } from '@tanstack/server';
import { getSearchPerformance } from '../shared/searchPerformance';

export const searchPerformance = defineServerFunction({
  handler: async (input) => {
    const data = await getSearchPerformance(input);
    return { data };
  },
});

Orchestrating Complex Workflows

Multi-step jobs use the workflow engine defined in src/server/workflows/:

// src/server/workflows/SiteAuditWorkflow.ts
import { createWorkflow } from '@tanstack/workflow';
import { crawlPhase } from './siteAuditWorkflowCrawl';
import { processPhase } from './siteAuditWorkflowPhases';

export const SiteAuditWorkflow = createWorkflow({
  steps: [crawlPhase, processPhase],
});

Database Client Configuration

The PostgreSQL client in src/db/pg/client.ts provides a connection interface:

// src/db/pg/client.ts
import { Pool } from 'pg';
export const pgPool = new Pool({ connectionString: process.env.DATABASE_URL });
export const query = (sql: string, params?: any[]) => pgPool.query(sql, params);

Summary

  • The root src/ directory contains the entire backend application organized by function: workflows, routes, database layers, shared logic, and middleware.
  • Dual database support is implemented through separate src/db/d1/ and src/db/pg/ directories, with migrations split between drizzle/ and drizzle-pg/.
  • TanStack Server Functions reside in src/serverFunctions/ and are orchestrated by workflows in src/server/workflows/ for complex operations like site audits.
  • API routes in src/routes/ map HTTP paths to server functions, while src/middleware/ handles authentication and error handling.
  • Operational directories at the repository root (e2e/, scripts/, docs/, runbooks/) support testing, deployment, and maintenance workflows.

Frequently Asked Questions

What is the difference between src/server/ and src/serverFunctions/?

The src/server/ directory contains TanStack Server infrastructure and workflow orchestrators that coordinate multi-step background jobs, while src/serverFunctions/ (note the exact naming convention in the repository) houses individual server function implementations exposed directly to the client through TanStack routing. Workflows like SiteAuditWorkflow.ts compose these functions into complex pipelines with retry logic and state management.

How does open-seo support both SQLite and PostgreSQL?

The codebase maintains database-agnostic schemas in src/db/schema.ts while isolating driver-specific implementations in subdirectories: src/db/d1/ for Cloudflare's D1 SQLite and src/db/pg/ for PostgreSQL. Migration files are similarly separated between drizzle/ (SQLite/D1) and drizzle-pg/ (PostgreSQL), allowing the application to target either backend based on the DATABASE_URL environment variable and build configuration.

Where should I add new API endpoints in the open-seo backend?

New API endpoints require two additions: first, create the server function implementation in src/serverFunctions/ using defineServerFunction from TanStack, then map the HTTP route in src/routes/ (typically under src/routes/api/). For endpoints requiring authentication, apply the ensureUser middleware from src/middleware/ensureUser.ts in the route definition to validate the session before handler execution.

What directory contains the business logic for Google Search Console integration?

Google Search Console integration logic resides in src/shared/gsc.ts within the src/shared/ directory. This location houses reusable business logic that can be imported by both server functions and workflow steps, keeping third-party service implementations separate from core API routing code and allowing GSC utilities to be tested independently.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →