CLOSE
Monorepo Architecture and Workspace Setup

Monorepo Architecture and Workspace Setup

Updated on 30 Jun, 2026 15 mins read 193 views

Before implementing business logic, we must decide how the source code will be organized.

For small project, a single application repository if often sufficient.

Example:

project/
├── frontend
└── backend

However, as the system grows, multiple problems emerge:

  • Code duplication
  • Shared type mismatches
  • Dependency management issues
  • Difficult deployments
  • Version synchronization problems.

PeerDrop is designed to scale beyong a simple MVP.

Future plans include:

  • Web application
  • Mobile application
  • Desktop application
  • Multiple backend services
  • Shared SDKs
  • Shared UI libraries

Because of these goals, we use a Monorepo Architecture.

What is a Monorepo?

A monorepo (Monolithic Repository) is a repository that contains multiple applications and packages inside a single source control repository.

Instead of:

peerdrop-web
peerdrop-api
peerdrop-mobile
peerdrop-shared

We maintain:

peerdrop/
├── apps
├── packages
└── tooling

Everything evolves together.

Monorepo Benefits

Benefit 1: Shared Code

Instead of:

Copy Paste

we use:

import { JoinSessionDto } from '@peerdrop/shared';

Benefit 2: Easier Refactoring

Suppose:

sessionId: string

becomes:

sessionCode: string

In a monorepo:

One change

affects all consumers.

Benefit 3: Atomic Changes

Frontend change:

+

Backend change:

+

Shared package change

can all be committed together.

Benefit 4: Better Developer Experience

Single command:

pnpm install

Benefit 5: Future Scalability

Future applications:

Web
Mobile
Desktop
CLI
Admin Panel

can all live in the same repository.

Workspace Structure

Current project structure:

ThePeerDrop/

├── apps/
│   ├── api/
│   └── web/
│
├── packages/
│
├── docs/
│
├── pnpm-workspace.yaml
├── package.json
└── turbo.json

Understanding the Apps Directory

The apps directory contains executable applications.

apps/api

Backend service:

NestJS
Socket.IO
TypeScript

Responsibilties:

Signaling
Sessions
WebSocket Communication

Structure:

apps/api/

├── src
├── test
├── dist
├── package.json
├── tsconfig.json
└── nest-cli.json

apps/web

Frontend application

Technology:

Next.js
React
TypeScript

Responsibilities:

UI
WebRTC
User Interaction

Structure:

apps/web/

├── app
├── public
├── package.json
└── next.config.ts

Understanding the Packages Directory

Packages contain reusable code.

Current state:

packages/

Empty.

Future structure:

packages/

├── shared/
├── ui/
├── sdk/
├── config/
└── types/

Shared Package

Future package:

packages/shared

Purpose:

DTOs
Interfaces
Constants
Validators

Example:

export interface JoinSessionDto {
  sessionId: string;
}

Used by:

Frontend
Backend

simultaneously.

UI Package

Future package:

packages/ui

Contains:

Buttons
Cards
Inputs
Modals
Progress Bars

Example:

<Button />

shared across:

Web
Desktop
Mobile

SDK Package

Future package:

packages/sdk

Contains:

Socket Client
API Client
Session Client
WebRTC Helpers

Example:

import { PeerDropClient }
 from '@peerdrop/sdk';

Configuration Package

Future package:

package/config

Contains:

ESLint
Prettier
TypeScript Config

Example:

Shared linting rules

for every application.

Workspace Configuration

The monorepo is managed by PNPM Workspaces.

File:

pnpm-workspace.yaml

Example:

packages:
  - apps/*
  - packages/*

Meaning:

All apps
All packages

becomes workspace members.

Root Package.json

The root package.json controls the entire repository.

Example:

{
  "name": "the-peer-drop",
  "private": true
}

Important:

"private": true

prevents accidental publication to npm.

Why We Use PNPM

Several package managers exist.

Examples:

npm
yarn
pnpm

We chose PNPM because:

Faster Installation

PNPM uses a global package store.

Instead of:

Project A
Project B
Project C

Three Copies

PNPM stores:

One Copy

and creates links.

Lower Disk Usage

Traditional:

node_modules

can become enormous.

PNPM significantly reduces storage usage.

Better Workspace Support

PNPM was designed with monorepos in mind.

Why We Use Turbo

As the monorepo grows:

Web
API
Shared Packages

need coordinated builds.

Turbo helps manage:

Builds
Tests
Linting
Caching

across all applications.

Current Development Workflow

When working on PeerDrop:

Install dependencies:

pnpm install

Run backend:

pnpm --filter api start:dev

Run frontend

pnpm --filter web dev

Build all applications:

pnpm build
Buy Me A Coffee

Leave a comment

Your experience on this site will be improved by allowing cookies Cookie Policy