Monorepo Architecture
How the YeetCode monorepo is organized and why.
YeetCode uses a Bun workspace monorepo orchestrated by Turborepo. The repo is split into four workspace directories, each with a distinct purpose.
Workspace Layout
yeetcode/
├── packages/* # Shared libraries consumed by other workspaces
├── apps/* # User-facing applications (Next.js)
├── apps/* # Backend services (Convex)
└── tooling/* # Shared configuration (TypeScript presets)These are declared in the root package.json:
{
"workspaces": [
"packages/*",
"tooling/*",
"apps/*",
"apps/*"
]
}Package Naming
All packages use the @yeetcode/ scope:
| Package | Location | Purpose |
|---|---|---|
@yeetcode/email | packages/email | React Email templates and render utilities |
@yeetcode/typescript | tooling/typescript | Shared TypeScript config presets |
@yeetcode/convex-backend | apps/convex | Convex backend (private) |
Cross-Package Dependencies
Packages reference each other using Bun's workspace:* protocol:
{
"dependencies": {
"@yeetcode/email": "workspace:*",
"@yeetcode/typescript": "workspace:*"
}
}This ensures you always use the local workspace version rather than a published one.
Repo-Level Tooling
The root package.json contains repo-wide scripts:
bun run dev— Runsturbo dev --parallelacross all workspacesbun run build— Builds all packages respecting the dependency graphbun run lint— Runs workspace linting + sherif for monorepo consistency checksbun run format— Formats everything with Biomebun run typecheck— Type-checks all packagesbun run clean— Removes allnode_modulesviagit clean -xdfbun run clean:workspaces— Cleans workspace build artifacts (.turbo,.next,dist, etc.)
Sherif
The repo uses sherif (bun lint:repo) to enforce monorepo best practices — consistent dependency versions, correct workspace references, and proper package structure.