Open-SEO `src` Folder Structure: Complete Guide to Main Components and Modules
The src folder in open-seo contains eight core modules—entry points, types, shared utilities, server functions, middleware, lib, db, and environment definitions—that implement a layered back-end architecture for SEO tooling APIs.
The open-seo repository by every-app implements a production-ready SEO analysis platform. Understanding its src folder structure is essential for contributors, self-hosters, and developers extending the platform. This guide breaks down each module with direct references to source files and practical code patterns.
Entry Points: Application Bootstrap and HTTP Server
The top-level entry files initialize the runtime and wire together the routing layer.
src/start.ts– Bootstraps the Node.js process and calls the server factorysrc/server.ts– Creates the HTTP server instance with middleware mountingsrc/router.tsx– Defines the React-based router configurationsrc/routeTree.gen.ts– Auto-generated route tree from TanStack Router conventions
These four files form the inversion of control boundary: start.ts imports server.ts, which mounts router.tsx, which dispatches to server functions based on routeTree.gen.ts definitions.
Types Module: Zod Schema Definitions (src/types)
All data contracts between front-end and back-end live in src/types. Every API payload, database entity, and external integration response is validated through Zod schemas.
Key schema files include:
src/types/schemas/projects.ts– Project creation, update, and metadata validationsrc/types/schemas/keywords.ts– Keyword tracking inputs and ranking data structuressrc/types/schemas/audit.ts– Lighthouse audit configuration and results
Using Zod at the perimeter ensures runtime type safety and generates TypeScript inference for client-side code.
Shared Utilities: Reusable Business Logic (src/shared)
The src/shared module contains stateless, pure functions that encapsulate domain logic used across multiple endpoints. This layer prevents code duplication and enables unit testing without database dependencies.
| File | Responsibility |
|---|---|
src/shared/targetDetection.ts |
Detects page targets for auditing (single page vs. site-wide) |
src/shared/tag-colors.ts |
Color coding logic for SEO metric visualization |
src/shared/rank-tracking.ts |
Position change calculations and historical trend analysis |
src/shared/lighthouse.ts |
Chrome Lighthouse integration and result normalization |
src/shared/gsc.ts |
Google Search Console API helpers and data transformation |
These utilities are imported by server functions but never import from src/serverFunctions—maintaining a strict dependency direction toward stability.
Server Functions: Public API Endpoints (src/serverFunctions)
Each file in src/serverFunctions corresponds to a route group exposed to the front-end. These act as controllers: they parse requests, delegate to shared utilities, and serialize responses.
Primary endpoint modules:
src/serverFunctions/dashboard.ts– Aggregated metrics and KPI summariessrc/serverFunctions/projects.ts– CRUD operations for SEO projectssrc/serverFunctions/keywords.ts– Keyword management and ranking historysrc/serverFunctions/backlinks.ts– Backlink profile analysis and monitoringsrc/serverFunctions/audit.ts– On-page SEO audit execution and retrieval
Server functions receive an authentication context (ctx) containing userId and are responsible for authorization checks before data access.
Middleware: Cross-Cutting Concerns (src/middleware)
HTTP middleware intercepts requests before they reach server functions:
src/middleware/errorHandling.ts– Centralizes error serialization and logging; ensures consistent API error shapessrc/middleware/ensureUser.ts– Validates Cloudflare Access tokens, refreshes sessions, and attaches user context
Middleware runs in sequence for every incoming request, establishing the security and observability baseline.
Lib Module: Low-Level Infrastructure (src/lib)
The src/lib folder holds framework-agnostic helpers that would work in any Node.js context:
src/lib/auth.ts– JWT verification, session encryption, and password handlingsrc/lib/auth-turnstile.ts– Cloudflare Turnstile bot protection verificationsrc/lib/selfhost-preflight.ts– Runtime checks for self-hosted deployments (environment validation, database connectivity)
These modules have no dependencies on src/shared or src/serverFunctions, making them safe to import anywhere.
Database Layer: Schema and Provider (src/db)
Data persistence is abstracted through a thin wrapper over SQLite/D1:
src/db/schema.ts– Core table definitions using Prisma-style syntaxsrc/db/provider.ts– Connection pooling and query builder configurationsrc/db/telemetry.schema.ts– Analytics and usage tracking tables- Domain-specific extensions for billing, GSC data, and audit storage
The provider pattern allows seamless switching between local SQLite (development) and Cloudflare D1 (production) without code changes in consuming layers.
Environment Types (src/env.d.ts)
Global TypeScript declarations for runtime environment variables live in a single file:
// src/env.d.ts
declare namespace NodeJS {
interface ProcessEnv {
DATABASE_URL: string;
CLOUDFLARE_ACCOUNT_ID: string;
TURNSTILE_SECRET_KEY: string;
// ... additional env vars
}
}
This enables IntelliSense and compile-time validation for all process.env accesses.
Working with Open-SEO Modules: Code Examples
Fetching Dashboard Data (Client-Side)
async function loadDashboard() {
const resp = await fetch('/api/dashboard', {
credentials: 'include', // sends authentication cookie
});
if (!resp.ok) {
throw new Error(`Dashboard request failed: ${resp.status}`);
}
const data = await resp.json();
return data;
}
Calling Server Functions Directly (Internal)
import { getProjects } from '@/serverFunctions/projects';
async function demoProjects() {
const ctx = { userId: '12345' as const };
const projects = await getProjects(ctx);
console.log('Projects for user →', projects);
}
Using Shared Rank-Tracking Utilities
import { calculateRankChange } from '@/shared/rank-tracking';
const previous = 12;
const current = 8;
const change = calculateRankChange(previous, current);
// change = 4 (improvement)
Querying the Database
import { db } from '@/db';
async function countBacklinks() {
const result = await db.selectFrom('backlinks')
.selectCount('id')
.where('domain', '=', 'example.com')
.executeTakeFirst();
return result?.count ?? 0;
}
Summary
The open-seo src folder implements a layered architecture with clear separation of concerns:
- Entry points bootstrap and route HTTP traffic
- Types enforce data contracts with Zod validation
- Shared utilities house reusable domain logic for SEO calculations and integrations
- Server functions expose typed API endpoints to the front-end
- Middleware handles authentication and error normalization
- Lib provides authentication, bot protection, and deployment helpers
- DB abstracts persistence with schema-first table definitions
- Environment types ensure type-safe configuration access
This structure enables horizontal scaling of API surface area while maintaining testability and preventing circular dependencies.
Frequently Asked Questions
What is the purpose of src/shared versus src/serverFunctions in open-seo?
src/shared contains stateless, reusable business logic (rank calculations, Lighthouse parsing) that multiple endpoints need. src/serverFunctions are the API controllers themselves—they orchestrate shared utilities, validate inputs, and handle HTTP specifics. Keeping them separate allows testing business logic without mocking HTTP infrastructure.
How does open-seo handle database portability between SQLite and Cloudflare D1?
The src/db/provider.ts file abstracts connection details. Schema definitions in src/db/schema.ts use generic SQL patterns compatible with both engines. At runtime, the DATABASE_URL environment variable determines which driver initializes, with no code changes required in server functions or shared utilities.
Where is authentication implemented in the open-seo codebase?
Authentication spans three locations: src/lib/auth.ts for core JWT and session cryptography, src/lib/auth-turnstile.ts for bot protection, and src/middleware/ensureUser.ts for request-level token validation. This split separates cryptographic primitives from HTTP-layer enforcement.
Can I add new API endpoints to open-seo without modifying existing files?
Yes. Create a new file in src/serverFunctions/ following the established pattern: export async functions that accept a ctx parameter, validate inputs with src/types schemas, delegate to src/shared utilities, and return typed responses. The TanStack Router convention in src/routeTree.gen.ts will automatically include new files if they follow the naming convention.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →