Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to manage monorepo with Git

Managing a monorepo in Git requires strategies that keep clone times fast, working directories focused, and commits attributable to specific packages — problems that become severe as the repository grows. As the creator of CoreUI with 25 years of open-source development experience, I manage a monorepo with multiple framework packages and rely on sparse checkout, shallow clones, and conventional commits to keep the workflow efficient. The key techniques are: sparse checkout to only fetch files you need, partial clone to avoid downloading all objects, and conventional commit prefixes to identify which package each commit affects. Git’s built-in tools handle all of this — no third-party tooling required for the Git layer itself.

Use partial clone and sparse checkout to minimize what you download.

# Partial clone - download commit/tree objects but not blob objects
git clone --filter=blob:none --sparse https://github.com/org/monorepo.git
cd monorepo

# Initialize sparse checkout with cone mode (faster pattern matching)
git sparse-checkout init --cone

# Check out only the packages you need
git sparse-checkout set packages/react packages/shared

# List what's currently checked out
git sparse-checkout list

--filter=blob:none skips downloading file contents on clone — blobs are fetched on demand when you access them. --sparse starts with only the root directory checked out. sparse-checkout set specifies which directories to include in your working tree.

Add or Remove Directories from Sparse Checkout

Expand or shrink your working tree without re-cloning.

# Add the Vue package to your working tree
git sparse-checkout add packages/vue

# Remove the Angular package from your working tree
git sparse-checkout set packages/react packages/vue packages/shared
# (list all directories you want, omitting the ones to remove)

# Check out everything (disable sparse checkout)
git sparse-checkout disable

Your local clone still has the full history — sparse checkout only controls which files are in your working directory. Other packages’ files are fetched on demand.

Using Git Worktrees for Parallel Work

Work on multiple packages simultaneously without switching branches.

# Add a worktree for the react package on a feature branch
git worktree add ../react-feature feature/react-v2

# List all worktrees
git worktree list

# Work in each directory independently
cd ../react-feature
# make changes, commit...

# Remove the worktree when done
git worktree remove ../react-feature

Each worktree has its own working directory and HEAD pointing to a different branch, but they share the same .git object store. No re-cloning, no duplicate downloads.

Conventional Commits for Package Attribution

Prefix commits with the affected package for clear history.

# Commit format: type(package): description
git commit -m "feat(react): add CDropdown virtualization support"
git commit -m "fix(angular): resolve sidebar collapse animation glitch"
git commit -m "chore(shared): update TypeScript to 5.4"
git commit -m "docs(vue): update CTable API documentation"

Tools like lerna, changesets, or nx parse these conventional commit prefixes to determine which packages changed and generate package-specific changelogs automatically.

Best Practice Note

This is the same Git workflow approach used in the CoreUI monorepo. Combine sparse checkout with CI optimizations — for example, use git diff HEAD~1 --name-only in CI to detect which packages changed and only build/test those packages. For dependency management across packages, use pnpm workspaces or npm workspaces to hoist shared dependencies. For very large teams, consider git maintenance commands to keep the repository performant on all developer machines.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to Open Link in a New Tab in HTML?
How to Open Link in a New Tab in HTML?

What is the difference between sort and toSorted in JavaScript?
What is the difference between sort and toSorted in JavaScript?

How to get element ID in JavaScript
How to get element ID in JavaScript

How to loop through a 2D array in JavaScript
How to loop through a 2D array in JavaScript

Answers by CoreUI Core Team