Monorepo, nebo více repozitářů? Praktické srovnání pro malé týmy
Výhody a nevýhody monorepa a polyrepa, nástroje (npm workspaces, pnpm, Turborepo, Nx), CI jen pro změněné části, CODEOWNERS a postup migrace pomocí git subtree.
Máte frontend, backend, sdílenou knihovnu a pár skriptů na nasazení. Dát vše do jednoho repozitáře (monorepo), nebo každou část zvlášť (polyrepo)? Obě cesty jsou legitimní. Rozhoduje velikost týmu, provázanost kódu a to, jak nasazujete.
Rozdíl v kostce
Monorepo Polyrepo
firma/platforma firma/web
├── apps/ firma/api
│ ├── web/ firma/shared-utils
│ └── api/ firma/infra
├── packages/
│ └── shared-utils/
└── infra/
Srovnání
| Hledisko | Monorepo | Více repozitářů |
|---|---|---|
| Změna napříč částmi (API + frontend) | jeden PR, atomický commit | několik PR, nutná koordinace pořadí |
| Sdílený kód | import přímo ze složky | publikovat balíček, řešit verze |
| Konzistence nástrojů (lint, formát) | jedna konfigurace | v každém repu zvlášť, rozjíždí se |
| CI | složitější – je třeba stavět jen změněné | jednoduché, každé repo své |
| Oprávnění | jemně jen přes CODEOWNERS a pravidla | přirozeně per repozitář |
| Velikost repozitáře | roste, klon trvá déle | malé repozitáře |
| Nezávislé verzování a releasy | jde, ale vyžaduje nástroje | přirozené |
| Orientace pro nového člověka | vše na jednom místě | nutné vědět, co kde je |
Kdy dává smysl monorepo
- Malý až střední tým, který na všem pracuje společně.
- Části jsou těsně provázané – změna API znamená změnu frontendu.
- Sdílíte typy, validace nebo komponenty mezi aplikacemi.
- Chcete jednotný lint, testy a závislosti.
Kdy více repozitářů
- Nezávislé týmy s vlastním rytmem vydávání.
- Části s odlišnou úrovní přístupu (např. open source knihovna vs. interní aplikace).
- Komponenty v různých jazycích a ekosystémech bez sdíleného kódu.
- Knihovna používaná i mimo vaši firmu – potřebuje vlastní verzování a releasy.
Monorepo v JavaScriptu: workspaces
Základní podpora je přímo v npm, pnpm i Yarn. Příklad s npm workspaces, kořenový package.json:
{
"name": "platforma",
"private": true,
"workspaces": ["apps/*", "packages/*"]
}
npm install # nainstaluje vše a propojí lokální balíčky
npm run build --workspace=apps/web # skript v jednom balíčku
npm run test --workspaces --if-present # ve všech
Aplikace apps/web pak může mít v závislostech "@firma/shared-utils": "*" a npm ji propojí se složkou packages/shared-utils.
pnpm používá soubor pnpm-workspace.yaml:
packages:
- "apps/*"
- "packages/*"
a příkazy s filtrem: pnpm --filter web build.
Při větším počtu balíčků pomohou Turborepo nebo Nx – řeší pořadí buildů podle závislostí a cache výsledků, takže se znovu nestaví to, co se nezměnilo.
V Pythonu podobně fungují workspaces ve správci uv nebo prosté instalace lokálních balíčků v editable režimu (pip install -e packages/shared).
CI v monorepu: spouštět jen to, co se změnilo
GitHub Actions umí filtrovat podle cest:
name: API
on:
pull_request:
paths:
- "apps/api/**"
- "packages/shared-utils/**"
- ".github/workflows/api.yml"
jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/api
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
Pozor na ochranu větve: pokud je workflow označený jako povinný check a kvůli filtru paths se nespustí, PR zůstane čekat. Řešením je povinný souhrnný job, který běží vždy, nebo filtrování až uvnitř workflow (např. akce dorny/paths-filter).
Vlastnictví kódu v monorepu
Soubor .github/CODEOWNERS přiřadí recenzenty podle složek:
/apps/web/ @firma/frontend
/apps/api/ @firma/backend
/infra/ @firma/devops
Viz také pull requesty a code review.
Polyrepo bez bolesti
Pokud zvolíte více repozitářů:
- Sdílený kód publikujte jako balíček (GitHub Packages, npm, PyPI) s SemVer.
- Používejte šablonu repozitáře (Settings → Template repository) se společnou konfigurací lintu a CI.
- Opakující se CI kroky dejte do reusable workflow (
on: workflow_call) v jednom repozitáři a volejte je z ostatních. - Udržujte přehled závislostí – Dependabot nebo Renovate.
Migrace: spojení repozitářů se zachováním historie
git clone [email protected]:firma/platforma.git && cd platforma
git subtree add --prefix=apps/api [email protected]:firma/api.git main
git subtree add vloží celé repozitáře do podsložky včetně historie commitů (bez parametru --squash).
Opačný směr – vyčlenění složky do samostatného repozitáře – zvládne git filter-repo --subdirectory-filter apps/api na čerstvém klonu.
Velké monorepo a rychlost Gitu
Když repozitář naroste, pomohou:
git clone --filter=blob:none [email protected]:firma/platforma.git # částečný klon
git sparse-checkout set apps/web packages/shared-utils # jen vybrané složky
Doporučení
Pro většinu malých týmů a startupů je dobrým výchozím bodem monorepo s workspaces – jeden PR pro změnu napříč aplikacemi ušetří hodně koordinace. Na více repozitářů přejděte, až pro to budete mít konkrétní důvod: samostatný tým, veřejnou knihovnu nebo odlišná přístupová práva.