OpenSEO Monorepo Structure: A Complete Guide to the pnpm Workspace Layout
OpenSEO organizes its entire codebase as a pnpm workspace monorepo, isolating the Next.js frontend, Cloudflare Worker MCP server, shared TypeScript utilities, and Drizzle PostgreSQL schema into distinct packages while maintaining unified dependency management at the repository root.
The every-app/open-seo repository leverages pnpm workspaces to colocate multiple deployable units within a single version-controlled codebase. This OpenSEO monorepo structure enables parallel development of the React dashboard, edge-deployed workers, and database layers while ensuring type safety and code reuse across package boundaries.
Root-Level Configuration and Shared Resources
The OpenSEO monorepo structure relies on the pnpm-workspace.yaml file at the repository root to define workspace boundaries and dependency overrides. This configuration serves as the entry point that instructs pnpm to treat the repository as a unified monorepo rather than a collection of independent projects.
Key root-level paths include:
pnpm-workspace.yaml– Declares workspace globs and transitive dependency version overridesREADME.md– Project overview, self-hosting guides, and contribution documentationdocs/– Human-focused deployment and development guides, includingdocs/SELF_HOSTING_DOCKER.mdanddocs/LOCAL_DEVELOPMENT.mdpublic/– Static assets such as favicons, logos, and manifest files consumed by the frontenddrizzle-pg.config.ts– Root-level configuration for the Drizzle ORM pointing to PostgreSQL schema definitions
Workspace Packages and Architecture
Below the root, the OpenSEO monorepo structure organizes functionality into four primary workspace packages. Each directory maintains its own package.json, src/ folder, and build configuration, allowing independent deployment while sharing source code through workspace references.
frontend/ – Next.js Dashboard Application
The frontend/ directory houses the React/Next.js UI that renders the OpenSEO dashboard and AI-enabled workflow interfaces. This package consumes the MCP server through generated API clients and renders analytics visualizations. Key files include frontend/package.json, frontend/next.config.js, and the component tree under frontend/src/.
worker/ – Cloudflare MCP Server
Located in worker/, this package implements Cloudflare Workers that expose Micro-service Control Protocol (MCP) endpoints for AI agents. It manages authentication, request routing, and database layer communication. Configuration resides in worker/wrangler.toml alongside worker/package.json and the handler implementations in worker/src/.
shared/ – Cross-Cutting TypeScript Utilities
The shared/ package centralizes Zod schemas, API-client helpers, and type definitions used by both the frontend and worker. By exporting utilities via the @open-seo/shared alias defined in shared/package.json, this package prevents type drift between the UI and server layers.
drizzle-pg/ – Database Schema and Migrations
The drizzle-pg/ directory contains database-first schema definitions and pure SQL migration scripts managed by Drizzle ORM. The migrations are applied using the pnpm db:migrate command, which reads the drizzle-pg.config.ts configuration and executes SQL files stored under drizzle-pg/.
Dependency Management and Workspace Linking
All packages in the OpenSEO monorepo structure share a single pnpm-lock.yaml at the repository root. When you run pnpm install from the top level, pnpm resolves versions once and creates symlinks between workspace packages. This allows the frontend and worker to import shared code using standard package syntax rather than relative file paths.
Both the UI and worker reference shared types through the workspace alias:
// frontend/src/components/KeywordList.tsx
import { Keyword } from '@open-seo/shared/types';
// worker/src/handlers/keyword.ts
import { Keyword } from '@open-seo/shared/types';
Both imports resolve to the same definition at shared/src/types.ts, ensuring compile-time type safety across the monorepo boundary without code duplication.
Development Workflow and Build Scripts
The root package.json aggregates scripts that delegate to individual packages in the OpenSEO monorepo structure. You can orchestrate the entire development stack or isolate specific services using pnpm filters:
pnpm dev:frontend– Starts the Next.js development server in watch modepnpm dev:worker– Launches the Cloudflare Worker locally using wranglerpnpm db:migrate– Applies pending SQL migrations fromdrizzle-pg/against the configured PostgreSQL instance
Each package maintains its own tsconfig.json, enabling independent compiler flags while preserving the ability to reference sibling packages. This isolation ensures the frontend can be bundled as a static site while the worker deploys to Cloudflare's edge runtime without configuration conflicts.
Summary
- OpenSEO uses
pnpm-workspace.yamlat the repository root to define the monorepo structure and workspace boundaries - The codebase splits into
frontend/,worker/,shared/, anddrizzle-pg/packages with independent build configurations - A single root-level
pnpm-lock.yamlmanages dependencies across all packages through pnpm symlinks - Code sharing occurs via workspace references like
@open-seo/sharedrather than relative imports - Database migrations live in
drizzle-pg/and apply through thepnpm db:migratescript - Each package maintains isolated TypeScript configurations while supporting unified development scripts at the root
Frequently Asked Questions
What package manager does OpenSEO use for its monorepo structure?
OpenSEO uses pnpm with workspace configuration defined in pnpm-workspace.yaml. This enables efficient disk space usage through content-addressable storage and creates symlinks between local packages for seamless internal imports without publishing to a registry.
Where are the database migrations and schema defined in the OpenSEO monorepo?
Database migrations reside in the drizzle-pg/ directory as pure SQL files. The drizzle-pg.config.ts file at the repository root configures the Drizzle ORM connection and points to these migration scripts, which you apply using the pnpm db:migrate command from the workspace root.
How do the frontend and worker share TypeScript types in OpenSEO?
Both packages import shared definitions from the shared/ workspace package using the alias @open-seo/shared. This workspace reference resolves to shared/src/types.ts, ensuring that data contracts remain synchronized between the Next.js UI and Cloudflare Workers.
Can the worker and frontend be deployed independently?
Yes. Despite residing in the same repository, the frontend/ and worker/ packages maintain separate package.json files and build pipelines. The frontend can be deployed as a static Next.js site while the worker deploys separately to Cloudflare's edge network, allowing independent scaling and release cycles within the OpenSEO monorepo structure.
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 →