Open-SEO src Folder Structure Explained: Complete Codebase Guide

The src directory in open-seo is organized into ten purpose-driven folders (db, lib, middleware, routes, shared, serverFunctions, server, types, client) plus key root-level files that bootstrap the application, enforce clear separation between database access, business logic, API surfaces, and UI integration.

The open-seo repository by every-app follows a modular architecture that keeps SEO tooling code maintainable and testable. Every folder in src has a single responsibility, from low-level database providers to high-level TanStack Query wrappers. This guide walks through each directory with concrete file paths and usage patterns drawn directly from the source code.

Top-Level src Organization

The src folder contains eleven top-level items organized by technical concern rather than feature domain:


src/
├─ db/                     # Database schema and connection provider

├─ lib/                    # Low-level utilities (auth, OAuth, pre-flight checks)

├─ middleware/             # HTTP middleware for errors and auth

├─ routes/                 # Static API route definitions

├─ shared/                 # Reusable business logic

├─ serverFunctions/        # TanStack Server-Function endpoints

├─ server/                 # Background workflows and jobs

├─ types/                  # TypeScript definitions and Zod schemas

├─ client/                 # TanStack-Query client wrappers

├─ router.tsx              # Main React Router configuration

├─ routeTree.gen.ts        # Auto-generated route tree

├─ server.ts               # Express-like HTTP server entry

├─ start.ts                # Application bootstrap script

└─ env.d.ts                # Global TypeScript environment

This layout prioritizes vertical slicing—each layer depends only on layers below it, with types/ at the foundation and client/ at the consumer edge.

Database Layer: src/db/

The db folder abstracts all database concerns behind a provider pattern compatible with SQLite and Postgres.

File Responsibility
src/db/provider.ts Connection abstraction and query interface
src/db/schema.ts Prisma-style table definitions
src/db/*.schema.ts Domain-specific schema extensions

Server functions never import database drivers directly. Instead, they consume the provider singleton:

// src/serverFunctions/projects.ts
import { db } from '@/db/provider';

export async function getProject(req: Request) {
  const { id } = req.params;
  return await db.project.findUnique({ where: { id } });
}

Utility Layer: src/lib/

Pure, side-effect-free functions live in lib. These modules handle cross-cutting concerns without depending on the database or HTTP layer.

Middleware and server functions both import from lib, ensuring consistent auth behavior across the stack.

Middleware Layer: src/middleware/

Express-style HTTP middleware enforces request preconditions before routing logic executes.

These wrap the router and server functions to provide uniform error responses and user enforcement.

API Routes: src/routes/

Static route definitions expose HTTP endpoints for external clients. The structure follows Next.js conventions:


src/routes/api/
├─ health.ts          # Service health check endpoint

└─ auth/
   └─ $.ts            # Catch-all auth route handler

These routes delegate to server functions rather than implementing business logic directly.

Business Logic: src/shared/

The shared folder contains domain logic reused across server functions and UI components.

File Domain
src/shared/keyword-locations.ts Geographic keyword parsing
src/shared/rank-tracking.ts Ranking calculation algorithms
src/shared/billing.ts Subscription limit enforcement

This placement enables client-side preview calculations using the same logic as the server.

API Surface: src/serverFunctions/

TanStack Server-Functions form the primary API boundary between frontend and backend. Each file corresponds to a business domain:

// src/serverFunctions/rank-tracking.ts
import { createServerFunction } from '@tanstack/server';
import { getRankings } from '@/shared/rank-tracking';

export const getRankingsSF = createServerFunction(
  'rankings.get',
  async (input) => {
    return await getRankings(input.projectId);
  }
);

Other key files include src/serverFunctions/projects.ts for CRUD operations and src/serverFunctions/gsc.ts for Google Search Console integration.

Background Jobs: src/server/

Long-running workflows live in src/server/workflows/:

These operate directly on the database and shared logic, triggered by schedulers or frontend requests.

Type Safety: src/types/

Centralized TypeScript definitions prevent drift between layers:


src/types/
├─ vite-env.d.ts          # Vite environment augmentation

└─ schemas/
   ├─ projects.ts         # Project Zod schemas

   └─ keywords.ts         # Keyword Zod schemas

All other modules import from types/ to guarantee contract consistency.

Client Integration: src/client/

TanStack-Query configuration enables efficient data fetching with caching, retries, and optimistic updates:

// src/components/ProjectList.tsx
import { useQuery } from '@/client/tanstack-db';
import { getProjectsSF } from '@/serverFunctions/projects';

export function ProjectList() {
  const { data: projects, isLoading } = useQuery(
    ['projects'],
    getProjectsSF
  );
  // ...
}

The wrapper at src/client/tanstack-db/queryClient.ts standardizes query behavior across components.

Application Bootstrap

Three root-level files orchestrate startup:

File Role
src/start.ts Loads environment, initializes database, launches server
src/server.ts Configures HTTP pipeline with middleware and router
src/router.tsx Maps URLs to UI pages and server functions
src/routeTree.gen.ts Auto-generated route manifest

The router imports server functions and middleware to assemble the complete request pipeline.

Summary

  • src/types/ — Foundational schemas imported by all layers
  • src/db/ — Database provider pattern for SQLite/Postgres
  • src/lib/ — Pure utility functions (auth, OAuth, validation)
  • src/middleware/ — HTTP request preprocessing
  • src/routes/ — Static API endpoint definitions
  • src/shared/ — Reusable business logic (rankings, billing, keywords)
  • src/serverFunctions/ — TanStack Server-Function API surface
  • src/server/ — Background workflow implementations
  • src/client/ — TanStack-Query wrappers for UI consumption
  • Root files (start.ts, server.ts, router.tsx) — Bootstrap and wire the stack

Frequently Asked Questions

What database does open-seo use?

The codebase supports both SQLite and Postgres through an abstraction in src/db/provider.ts. The provider pattern lets operators swap storage backends without changing server function code.

How does authentication work across the stack?

src/lib/auth.ts implements core session and token validation. src/middleware/ensureUser.ts wraps HTTP requests to enforce authentication, integrating with Cloudflare Access and delegated auth providers. Both server functions and API routes apply this middleware consistently.

Where should new business logic be added?

Place reusable domain logic in src/shared/ if both frontend and backend need it. Implement API endpoints in src/serverFunctions/ using TanStack Server-Functions. Add database schema changes to src/db/schema.ts or a new *.schema.ts file.

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

src/routes/ holds static HTTP endpoint definitions for external API consumers. src/serverFunctions/ contains TanStack Server-Functions that provide type-safe RPC between the React frontend and backend with automatic caching and optimistic updates.

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 →