
September 10, 2026
11 min read
By Kokil Thapa | Last reviewed: September 2026
Choosing between one repository and many is not a fashion decision. Monorepo vs Polyrepo: Trade-offs affect how fast you ship, how safely you deploy, and who owns what when a payment webhook breaks at midnight. On real client projects—Laravel booking apps, WooCommerce stores, legal-tech portals—I have seen both layouts work and both fail for predictable reasons. This guide compares them the way a working engineer needs: CI pipelines, deploy paths, package boundaries, and the boring ops details that decide whether your team moves fast or fights Git every week. For related architecture reading, see our CI/CD guide for monorepos with multiple PHP apps.
What is the difference between a monorepo and a polyrepo?
A monorepo stores multiple applications, packages, or services in one Git repository. A polyrepo splits each app, library, or service into its own repository. The code may look similar on disk. The operational story is completely different.
In a monorepo, a single pull request can update a shared validation package and every consumer in one atomic commit. In a polyrepo, that same change becomes a choreographed sequence: publish package, bump version, open pull requests in three other repos, and hope nobody merges out of order.
Neither layout is inherently cleaner. A monorepo can become a junk drawer without folder conventions. A polyrepo can become a version-pinning nightmare without a release discipline. The right question is which pain your team can afford.
Common monorepo folder shapes
Laravel teams often use a layout like this:
company-platform/
├── apps/
│ ├── admin-api/ # Laravel 13
│ ├── customer-portal/ # Laravel 13 + Livewire
│ └── marketing-site/ # WordPress 7.1 or static
├── packages/
│ ├── billing-sdk/ # Shared PHP library
│ └── domain-events/ # Internal event contracts
├── composer.json # Root workspace (optional)
└── .gitlab-ci.yml # Path-filtered pipelines Polyrepo splits each path under apps/ and packages/ into separate remotes. Shared code ships through Composer (private Satis, GitLab package registry, or Packagist).
When should you choose a monorepo over a polyrepo?
Pick a monorepo when cross-cutting changes are frequent and your team is small enough to share one codebase culture. That pattern fits tightly coupled products: admin panel plus public API plus shared domain models.
I have maintained sister legal-tech sites that share deployment patterns but live in separate repos. That works because each site deploys independently and shares little runtime code. A booking platform with a supplier CRM, customer portal, and shared payment module is a different story. There, a monorepo often pays for itself within months.
- One team owns the full product surface.
- Shared PHP packages change weekly, not yearly.
- You need atomic refactors across apps (rename a column, update every consumer).
- CI can run path-filtered jobs so you do not test everything on every commit.
- You want one issue tracker context: one PR shows the full feature.
Tools like Turborepo and Nx exist because monorepos without build graph awareness get slow. PHP monorepos lean on Composer path repositories, shared CI templates, and selective test runners instead.
How does CI/CD differ between monorepo and polyrepo setups?
CI is where Monorepo vs Polyrepo trade-offs stop being abstract. A polyrepo pipeline is simple: one repo, one pipeline, one deploy target. A monorepo pipeline must answer a harder question on every push: what actually changed?
Without path filters, a typo in a README triggers full test suites for five Laravel apps. That burns GitLab runner minutes fast. On budget-sensitive Nepal client projects, that cost shows up quickly—often Rs 3,000–8,000/month (~USD 22–60) in CI alone if you are careless.
GitLab CI path rules for a PHP monorepo
This pattern mirrors what I use on Deployer 7 pipelines for multi-app platforms. It runs jobs only when relevant folders change:
test-admin-api:
rules:
- changes:
- apps/admin-api//*
- packages/billing-sdk//*
script:
- cd apps/admin-api
- composer install --no-interaction
- php artisan test
deploy-admin-api:
needs: [test-admin-api]
rules:
- if: $CI_COMMIT_BRANCH == "main"
changes:
- apps/admin-api/**/*
script:
- dep deploy admin-api -vvv Polyrepo pipelines skip the changes: block entirely. The trade-off appears downstream: updating a shared Composer package means tagging a release, then bumping dependencies in each consumer repo. Miss one repo and production drift begins.
For deeper pipeline design, read our monorepo CI/CD walkthrough for PHP apps and compare it with infrastructure-as-code trade-offs when deploy targets multiply.
What are the main Monorepo vs Polyrepo trade-offs for Laravel and PHP teams?
The table below is the comparison most architects actually need. Scores are practical, not academic. Your context shifts them.
| Criteria | Monorepo | Polyrepo |
|---|---|---|
| Cross-app refactor speed | Excellent — one PR, one review | Slow — coordinated releases across repos |
| Deploy blast radius | Higher if CI filters fail | Lower — each repo deploys alone |
| CI complexity | High — path rules, caching, graph tools | Low — one pipeline per repo |
| Access control | Harder — repo-wide read access | Easier — per-repo permissions |
| Shared package workflow | Path repos, instant local changes | Composer tags, semver discipline |
| Onboarding | One clone, steep folder learning curve | Many clones, simpler per-repo scope |
| Tooling fit (PHP/Laravel) | Good with Composer workspaces | Natural default for most agencies |
| Best team size | Small to mid, single product unit | Mid to large, separate squads |
Laravel 13 needs PHP 8.3 or higher. Laravel 12 runs on PHP 8.2 through 2027. Your repo layout does not change those requirements. It changes how painful a framework upgrade becomes. Upgrading Laravel across four polyrepos without a shared baseline is four separate migration projects. In a monorepo, you see every composer.json diff in one place.
Similar boundary questions appear in Laravel multi-tenancy trade-offs and GraphQL vs REST trade-offs—the theme is always where you draw the line between shared and isolated.
Composer path repositories in a monorepo
Link internal packages without publishing:
{
"repositories": [
{
"type": "path",
"url": "../../packages/billing-sdk",
"options": { "symlink": true }
}
],
"require": {
"company/billing-sdk": "*"
}
} Polyrepo consumers instead require a semver constraint against a private registry. That is cleaner for third-party boundaries. It is slower for daily iteration.
How do deployment and production ops change in each model?
Deployment is the trade-off engineers feel at 11 p.m. I run Deployer 7 with symlinked releases on Ubuntu 24 servers for multiple client platforms. The repo layout directly affects rollback stories.
In a polyrepo, rolling back App A never touches App B. Each deploy.php targets one hostname. In a monorepo, one mistaken deploy task can push the wrong release path if your Deployer stages share a server tree. I have seen stale cron entries point at old release paths after a monorepo restructure. That class of bug is rare in polyrepos because paths stay stable per project.
Production checklist that differs by layout
- Map every deploy stage to exactly one public hostname and one PHP-FPM pool.
- Store shared
.envsecrets outside release folders in both models. - Reload PHP-FPM after symlink swap so opcache picks up changed files.
- In monorepos, namespace queue workers and cron entries per app path.
- In polyrepos, document cross-service API version contracts explicitly.
- Automate off-site backups per database, not per repo layout—see off-site backup automation.
Server work overlaps with Linux system administration and ongoing support contracts. Repo choice does not remove that ops layer.
How should agencies and product teams decide which model fits?
Decision criteria beat ideology. Start with release coupling, not Git aesthetics.
Choose polyrepo when squads are independent, clients own separate codebases, or compliance demands strict repository access walls. A lawyer directory platform and a trek booking system should not share a repo just because one agency built both. They share an agency, not a runtime.
Choose monorepo when one product spans multiple deployables that must move together. A Laravel customer portal, admin CRM, and shared payment module on one platform is the classic win—similar to how client portals with document sharing and payments benefit from unified domain logic.
Hybrid patterns that work in 2026
Most agencies land on a hybrid. Product platforms live in a monorepo. Client brochure sites and WordPress 7.1 installs stay in polyrepos. WooCommerce 11.1 shops rarely belong inside an enterprise monorepo unless the same team owns custom plugins tied to a Laravel backend.
Enterprise buyers evaluating layout should involve enterprise application development planning early. Wrong repo boundaries cost more to fix than server sizing mistakes.
For API-heavy splits, pair this decision with API development practices and rate limiting guidance. Polyrepo service meshes need explicit contracts. Monorepo services still need HTTP boundaries—folder proximity is not an excuse to skip validation.
Migration path: polyrepo to monorepo without a big bang
Teams rarely rewrite history cleanly. A sane incremental path:
- Create a monorepo with
git subtreeor filtered imports preserving blame where possible. - Move shared libraries to
packages/with Composer path repos first. - Unify CI with path filters before merging deploy pipelines.
- Keep separate Deployer stages until one release breaks—then fix deliberately.
- Document ownership in
CODEOWNERSso monorepo scale does not erase accountability.
Ansible and server provisioning stay layout-agnostic. Your playbooks target hosts, not folders—see Ansible playbooks for PHP servers for the baseline either way.
Key Takeaways
- Monorepo vs Polyrepo trade-offs hinge on release coupling, not Git preference—shared weekly code favours monorepo; independent products favour polyrepo.
- Monorepos need path-filtered CI and clear folder conventions or runner costs and deploy risk spike fast.
- Polyrepos simplify permissions and deploy isolation but multiply version coordination work across Composer packages.
- Laravel and PHP teams should use Composer path repos in monorepos and private registry semver in polyrepos.
- Deployer 7 stages, cron paths, and PHP-FPM reload discipline matter more after consolidating repos.
- Hybrid layouts—monorepo for product, polyrepo for client sites—match most agency realities in 2026.
People Also Ask
Is monorepo better for small teams?
Usually yes, for one product with multiple apps. Small teams gain atomic changes and a single review surface. The monorepo becomes a liability when the team grows past clear ownership without CODEOWNERS and CI path filters.
Does Google use a monorepo because it is always superior?
No. Google’s monorepo fits their tooling, culture, and scale. Most PHP agencies lack Google's internal build graph infrastructure. Copy the pattern, not the assumption that one size fits all.
Can WordPress and Laravel live in the same monorepo?
Yes, but only when one team ships both on a coordinated release cycle. Otherwise WordPress 7.1 sites belong in separate repos with their own update cadence and plugin risk profile.
What tools help PHP monorepos besides Nx and Turborepo?
Composer path repositories, GitLab CI changes rules, PHPUnit with suite filters, Deployer multi-stage configs, and private Composer registries for packages that later extract to polyrepo consumers.
Pick the layout your deploy story can support
Monorepo vs Polyrepo trade-offs are really trade-offs about coordination cost versus isolation benefit. There is no trophy for picking the trendier layout. There is only whether your next cross-app change ships in one afternoon or three synchronized releases.
Audit your last five production incidents. If most involved version drift between repos, test a monorepo slice for shared packages. If most involved one bad deploy taking down unrelated apps, tighten polyrepo boundaries and CI filters. Validate JSON config shuffles during migration with our JSON formatter before they hit pipeline YAML.
Need help restructuring a Laravel platform, WooCommerce stack, or multi-app deploy pipeline? Review the portfolio for shipped examples, then contact us to plan a repo strategy that matches how your team actually releases software.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

