eduardweb.
Ajutor & ÎntrebăriIntermediar#nextjs#react#monorepo#turborepo#pnpm

Cum am structurat un monorepo cu 3 aplicații Next.js și 80% UI comun

De Delia Petre, 25 iul. 2026 · 11 vizualizări · 3 like-uri

Postat 25 iul. 2026
json
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "lint": {},
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

Am avut recent un proiect cu 3 aplicații Next.js (un dashboard de admin, o platformă B2C și un portal B2B) care împărțeau cam 80% din componentele de UI și utilitare. Inițial am plecat de la ideea clasică de a le ține în repo-uri separate cu un pachet de UI publicat pe npm private, dar am realizat rapid că pierdem ore înșir cu versionarea și CI-ul la fiecare schimbare de buton.

Așa am ajuns să migrăm totul într-un monorepo. Întrebarea mare a fost: mergem pe pnpm workspaces chior, punem Turborepo sau trecem direct la Nx?

Soluția 1: pnpm workspaces simplu fără build orchestrator

Am început cu cel mai simplu setup posibil: pnpm workspaces. Pentru împărțit codul între /apps/web, /apps/admin și /packages/ui, își face treaba de minune. Nu ai nevoie de tool-uri sofisticate ca să imporți un buton din @repo/ui direct în Next.js, mai ales că Next transpiles pachetele interne fără mari bătăi de cap.

Problema a apărut rapid în CI. Când rulai pnpm build, pnpm le executa secvențial sau paralel neoptimizat. Nu exista caching. La un proiect cu peste 40 de componente și 3 aplicații Next, build-ul pe GitHub Actions ajunsese la 8 minute. În plus, dacă modificam un fișier de CSS din UI, se reconstruiau toate cele 3 aplicații de la zero.

Turborepo: Calea de mijloc care a câștigat la noi

Am adăugat Turborepo peste pnpm workspaces în mai puțin de o oră. Fiind construit de echipa de la Vercel, integrarea cu Next.js e practic nativă.

Ce ne-a salvat din prima zi a fost Remote Caching. Am scăzut timpul de CI de la 8 minute la aproximativ 1.5 minute pentru că Vercel Cache stochează output-ul de la pachetele neschimbate. Dacă modific doar o pagină din dashboard-ul de admin, aplicația B2C și pachetul de UI sunt luate direct din cache.

Arhitectura de dosare pe care am rămas arată cam așa:

  • apps/admin (Next.js App Router)
  • apps/b2c (Next.js App Router)
  • apps/b2b (Next.js App Router)
  • packages/ui (Shadcn UI + Tailwind)
  • packages/config-typescript (tsconfig-uri comune)
  • packages/config-eslint (reguli de linting)

Trade-off-ul cu Turborepo? Este un task runner destul de simplist comparat cu Nx. Nu știe să-ți genereze automat dependency graph-uri avansate pentru dependențe implicite și nici nu oferă generator de cod. Dar sincer, pentru stack-ul nostru de JS/TS pur, simplitatea asta a fost un plus, nu un minus.

Când are sens Nx?

Am folosit Nx în trecut pe un proiect mai vechi cu 12 micro-frontends și Angular. Nx este un monstru de putere: știe exact ce fișier a atins ce aplicație, are vizualizare de grafic impecabilă și module boundary rules (să nu imporți din greșeală cod de backend în frontend).

Dar pentru 3 app-uri Next.js, Nx aduce o tonă de boilerplate. Fișiere project.json peste tot, abstractizări proprii peste execuția de comenzi și o curbă de învățare care pe colegii mei mai juniori i-a zăpăcit la început. Dacă nu ai o echipă dedicată de DevOps, Nx e de multe ori prea mult overhead pentru ce oferă.

Cum a rămas

Am rămas pe pnpm workspaces + Turborepo. Am obținut un setup în care o schimbare la un UI component se vede instant pe local cu HMR în toate cele 3 app-uri, iar build-urile de staging durează sub 2 minute.

Voi ce folosiți când aveți de împărțit un design system între mai multe aplicații Next? Ați rămas pe workspaces simple sau ați simțit nevoia de un orchestrator mai deștept?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.