# OpenSEO Monorepo Structure: A Complete Guide to the pnpm Workspace Layout

> Explore the OpenSEO monorepo structure, a pnpm workspace layout organizing Next.js, Cloudflare Workers, and shared utilities for efficient development and dependency management.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-09-05

---

**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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/pnpm-workspace.yaml) – Declares workspace globs and transitive dependency version overrides
- [`README.md`](https://github.com/every-app/open-seo/blob/main/README.md) – Project overview, self-hosting guides, and contribution documentation
- `docs/` – Human-focused deployment and development guides, including [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md) and [`docs/LOCAL_DEVELOPMENT.md`](https://github.com/every-app/open-seo/blob/main/docs/LOCAL_DEVELOPMENT.md)
- `public/` – Static assets such as favicons, logos, and manifest files consumed by the frontend
- [`drizzle-pg.config.ts`](https://github.com/every-app/open-seo/blob/main/drizzle-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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/frontend/package.json), [`frontend/next.config.js`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/worker/wrangler.toml) alongside [`worker/package.json`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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:

```typescript
// 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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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 mode
- `pnpm dev:worker` – Launches the Cloudflare Worker locally using wrangler
- `pnpm db:migrate` – Applies pending SQL migrations from `drizzle-pg/` against the configured PostgreSQL instance

Each package maintains its own [`tsconfig.json`](https://github.com/every-app/open-seo/blob/main/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.yaml`](https://github.com/every-app/open-seo/blob/main/pnpm-workspace.yaml) at the repository root to define the monorepo structure and workspace boundaries
- The codebase splits into `frontend/`, `worker/`, `shared/`, and `drizzle-pg/` packages with independent build configurations
- A single root-level [`pnpm-lock.yaml`](https://github.com/every-app/open-seo/blob/main/pnpm-lock.yaml) manages dependencies across all packages through pnpm symlinks
- Code sharing occurs via workspace references like `@open-seo/shared` rather than relative imports
- Database migrations live in `drizzle-pg/` and apply through the `pnpm db:migrate` script
- 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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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.