Most monorepo setups fall into one of two traps:
- ❌ Everything is duplicated per app → impossible to scale
- ❌ Everything is centralized → turns into a “god app”
After hitting both problems, I built a boilerplate that actually scales cleanly across multiple products.
🧠 The Idea
Instead of thinking:
“Each product is its own app”
I flipped it to:
“Products are modules. Apps are just runtimes.”
🧱 The Architecture
apps/
web/ → Next.js runtime
api/ → NestJS runtime
packages/
core/ → auth, db, logging, http
products/ → all business domains
shared/ → types, utils, validation
ui/ → design system
🔥 Key Concept
Each product looks like this:
packages/products/product-a/
backend/
frontend/
-
backend/→ NestJS modules -
frontend/→ UI + features
No duplication. No separate repos. No messy coupling.
⚙️ How It Works
Backend (NestJS)
Products plug into the API:
import { ProductAModule } from "@repo/products/product-a/backend";
@Module({
imports: [ProductAModule]
})
export class AppModule {}
Frontend (Next.js)
Products plug into the UI:
import { ProductAFeature } from "@repo/products/product-a/frontend";
⚡ Why This Is Better
1. No duplication
Auth, DB, and config live in core/ once.
2. Real scalability
Adding a new product = new folder, not a new app.
3. Clean boundaries
- products = business logic
- core = infrastructure
- apps = runtime only
4. Works with Turbo
- fast builds
- caching
- parallel dev
🧠 What I Learned (the hard way)
1. NodeNext breaks monorepos if you’re not careful
Use:
"module": "commonjs",
"moduleResolution": "node"
2. Every module needs an entry point
backend/index.ts
Otherwise imports fail silently.
3. Path aliases must be correct
"paths": {
"@repo/products/*": ["packages/products/*"]
}
No leading /.
4. Never mix core and product logic
That’s how monorepos rot.
🚀 What You Can Build With This
- SaaS platforms with multiple products
- internal tools ecosystems
- white-label systems
- modular startups (build fast, scale later)
📦 Example Use Case
Instead of:
- 10 repos
- 10 APIs
- 10 frontends
You get:
- 1 system
- shared infrastructure
- isolated products
⚠️ What This Is NOT
- Not microservices
- Not a simple starter template
- Not beginner-friendly (and that’s fine)
This is for when you actually care about scale and structure.
🧭 What’s Next
I’m planning to add:
- automatic product generator CLI
- dynamic module loading (no manual imports)
- per-product database isolation
- CI/CD pipelines per domain
💭 Final Thought
Most people scale by adding more apps.
That’s the wrong move.
Scale by composing systems, not duplicating them.
If you’re building something similar or thinking about monorepos, I’d like to hear how you’re structuring yours.
Top comments (0)