Monorepo vs Submodules: Developer Experience Comparison
๐ฌ Real-World Scenarios
Scenario 1: New Contributor Joins
#### With Submodules ๐ซ
# Step 1: Clone (5 min + understanding --recurse-submodules)
git clone --recurse-submodules https://github.com/larcjs/larc.git
cd larc
# Step 2: "Why am I in detached HEAD?" (15 min googling)
cd core
git status
# HEAD detached at 4f8d156...
# Step 3: Figure out how to work on code (10 min reading docs)
git checkout main
git pull
# Step 4: Realize every submodule needs this
./work-on-submodule.sh core
./work-on-submodule.sh ui
./work-on-submodule.sh apps
# ... repeat 8 times
# Total time: 30-45 minutes + confusion
#### With Monorepo ๐
git clone https://github.com/larcjs/larc.git
cd larc
npm install
# Total time: 2-3 minutes
# Ready to code!
Scenario 2: Add Feature Across Core + Components
#### With Submodules ๐ซ
# Step 1: Work on core
cd core
git checkout main
git pull
# edit files...
git add .
git commit -m "Add bus.broadcast() method"
git push origin main
# Step 2: Can't test with components yet! They don't have the change.
cd ../ui
git checkout main
git pull
git submodule update # Still old core!
# Step 3: Wait for meta repo to update submodule pointer
cd ../
git add core
git commit -m "Update core submodule"
git push
# Step 4: NOW update components
cd ui
git submodule update # Finally has new core
git pull
# edit files to use bus.broadcast()
git add .
git commit -m "Use new broadcast method"
git push origin main
# Step 5: Update meta repo again
cd ../
git add ui
git commit -m "Update components submodule"
git push
# Total: 5 separate git operations, 10-15 minutes
# Risk: Forgot to update meta repo, teammates can't get your changes
#### With Monorepo ๐
# Edit both at once
cd packages/core
# add bus.broadcast()...
cd ../components
# use bus.broadcast()...
# Test immediately - works!
# One atomic commit
git add packages/core packages/ui
git commit -m "Add and use bus.broadcast() method"
git push
# Total: 1 git operation, 2 minutes
# Teammates get both changes together, always in sync
Scenario 3: Fix Bug Found in Production
#### With Submodules ๐ซ
# Step 1: Which submodule has the bug?
cd larc
./pull-updates.sh --check
# Hmm, bug is in core...
# Step 2: Enter core, fix bug
cd core
git checkout main
git pull
# fix bug...
git add .
git commit -m "Fix critical bus memory leak"
git push origin main
# Step 3: Update meta repo
cd ../
git add core
git commit -m "Update core with memory leak fix"
git push
# Step 4: Deploy - but wait! Need to update production
cd /production/larc
./pull-updates.sh
# Oh no, forgot to update meta repo!
# Or did I? Let me check...
git log
cd core
git log
# Are these the right versions? ๐ค
# Total: 15-20 minutes, uncertainty
#### With Monorepo ๐
cd packages/core
# fix bug...
git add .
git commit -m "Fix critical bus memory leak"
git push
# Deploy
cd /production/larc
git pull
npm install
# Done! One commit, one pull, clear history
# Total: 5 minutes, confident it's right
Scenario 4: Review Pull Request
#### With Submodules ๐ซ
# PR says: "Update core and components"
# View PR #1 (core repo)
gh pr checkout 123
cd core
git checkout pr-branch
# review changes...
# View PR #2 (components repo)
cd ../ui
gh pr checkout 456
git checkout pr-branch
# review changes...
# View PR #3 (meta repo)
cd ../
gh pr checkout 789
# See: "Update core and components submodules"
# Wait, which commits exactly? Let me check...
git diff main --submodule
# Test together
./pull-updates.sh
npm run build # Does this even work?
# "Error: Cannot find module @larcjs/core v1.1.2"
# Oh, need to wait for npm publish... ๐คฆ
# Total: 3 PRs, 20+ minutes, can't test before merge
#### With Monorepo ๐
# One PR with all changes
gh pr checkout 123
# See everything together
git diff main
# Test immediately
npm install
npm run build
npm test
# Works!
gh pr merge 123
# Total: 1 PR, 5 minutes, tested before merge
Scenario 5: Onboard Junior Developer
#### With Submodules ๐ซ
Day 1:- Clone repo (30 min explaining --recurse-submodules)
- Explain git submodules concept (1 hour)
- Explain detached HEAD (30 min)
- Show them SUBMODULE-WORKFLOW.md (1 hour reading)
- Practice with work-on-submodule.sh (30 min)
- Total: ~3.5 hours before first code change
- Junior dev forgets to checkout main (3 times)
- Forgets to update meta repo after submodule change (2 times)
- Pushes to detached HEAD and loses commits (1 time)
- Senior dev spends 2 hours helping recover
#### With Monorepo ๐
Day 1:- Clone repo:
git clone ... && npm install(5 min) - Explain directory structure (10 min)
- Make first commit (5 min)
- Total: 20 minutes, productive immediately
- Junior dev works like any normal git repo
- No special knowledge required
- No lost commits
- Senior dev reviews PRs normally
๐ Metrics Comparison
| Metric | Submodules | Monorepo | Improvement | |--------|-----------|----------|-------------| | Clone time | 3-5 min | 1-2 min | 2-3x faster | | Setup time (new dev) | 30-45 min | 2-3 min | 15x faster | | Cross-package feature | 15 min, 5 commits | 2 min, 1 commit | 7x faster | | PR review complexity | 3 PRs, can't test | 1 PR, can test | 3x simpler | | Risk of mistakes | High (many steps) | Low (standard git) | Much safer | | Onboarding time | 3-4 hours | 20 minutes | 9x faster | | Context switching | High (switch repos) | Low (one repo) | Better focus | | CI/CD complexity | High (8 repos) | Low (1 repo) | Simpler |
๐ฐ Cost Analysis (Team of 5 Developers)
Submodules
- Daily overhead per dev: 10 min (submodule updates, detached HEAD fixes, context switching)
- Weekly per dev: 50 min
- Team per week: 250 min = 4.2 hours
- Cost per year (at $100/hr): $100 ร 4.2 ร 52 = $21,840
- Onboarding: 3 extra hours per new dev ร 2 new devs/year = $600
- Bug fixes due to version mismatches: ~2 hours/month ร 12 = $2,400
- Total annual cost: ~$24,840
Monorepo
- Daily overhead: ~1 min (standard git workflow)
- Weekly per dev: 5 min
- Team per week: 25 min = 0.4 hours
- Cost per year: $100 ร 0.4 ร 52 = $2,080
- Onboarding: Standard (no extra cost)
- Bug fixes: Rare (atomic commits prevent mismatches)
- Total annual cost: ~$2,080
๐ฏ Real Quotes from Developers
About Submodules ๐ซ
"Git submodules are the closest thing to version control hell" - Reddit developer
"Every time I use git submodules, I feel like I'm fighting git instead of using it" - HN comment
"We migrated away from submodules. Best decision ever." - Tech lead at major company
"Git submodules: perfect in theory, nightmare in practice" - Stack Overflow answer
About Monorepos ๐
"Switched to monorepo, developer happiness went way up" - Google engineer
"Monorepo lets us move fast without breaking things" - Facebook engineer
"One repo, one source of truth. Simple." - Shopify engineer
๐ข Who Uses Monorepos?
Major companies that chose monorepos:- Google (2B+ lines of code in one repo!)
- Facebook/Meta
- Microsoft
- Uber
- Airbnb
- Shopify
- Netflix (for frontend)
๐ Migration Effort
Time Investment
- Planning: 1-2 hours
- Migration: 4-6 hours (one-time)
- Testing: 2-3 hours
- Documentation updates: 1-2 hours
- Total: 8-13 hours one-time cost
Break-Even Point
At $100/hr, break even in:- Cost: $1,300 (13 hours)
- Savings: $1,903/month
- Break even: 0.7 months (3 weeks!)
๐ค Common Objections Answered
"But we want separate repositories for separate packages"
Answer: You can still publish separately! Packages publish to npm independently. Users don't see your internal structure."What about independent versioning?"
Answer: Monorepos support this. Use changesets or lerna. You can still do @larcjs/core v1.1.1 and @larcjs/ui v1.2.0."Won't the repo get huge?"
Answer: Not really. Code is small. Git is efficient. Facebook has 100GB+ repo, works fine. Yours will be <1GB."What about access control?"
Answer: Use CODEOWNERS file, branch protection, PR requirements. Modern GitHub/GitLab handle this well."We're already using submodules..."
Answer: Sunk cost fallacy. The best time to switch was before starting. The second best time is now.โ Decision Matrix
| If you value... | Use... | |----------------|--------| | Developer happiness | Monorepo โ | | Fast onboarding | Monorepo โ | | Simple workflow | Monorepo โ | | Atomic commits | Monorepo โ | | Easy testing | Monorepo โ | | Simple CI/CD | Monorepo โ | | Cost savings | Monorepo โ | | Pain and suffering | Submodules โ |
๐ฏ Bottom Line
Your project goal: Make developers' lives easier Current setup (submodules): Makes developers' lives harder Solution: Use a monorepo Action: Run./test-monorepo.sh and see for yourself!
"The best tool is the one that gets out of your way and lets you focus on building great software. Git submodules get in the way. Monorepos get out of the way."