How do I create nested repositories in GitHub?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
GitHub does not provide a special repository type called a nested repository. What people usually want is to keep one repository inside another project directory without losing the child project's independent history. In practice, that means choosing between Git submodules, Git subtree, or a simpler monorepo layout.
Decide What Kind of Boundary You Actually Need
Before creating anything, decide whether the child codebase is truly independent. If the inner project has its own releases, its own contributors, or needs to be reused by other repositories, keeping it separate makes sense. If the same team changes both codebases together all the time, a single repository is often the better design.
There are three common models:
- '
submodule: the parent stores a pointer to a specific commit in another repository' - '
subtree: the parent vendors the child repository content into its own history' - monorepo: both codebases live in one repository and no nesting exists at the Git level
The wrong long-term solution is usually a plain folder that contains its own .git directory but is not registered as a submodule. That may appear to work locally, but it creates confusing behavior for teammates and CI.
Use a Submodule When the Child Repository Is Truly Independent
Submodules are the most explicit way to nest one repository into another. The parent repository records which exact child commit should be checked out.
This creates a .gitmodules file and stages the submodule pointer in the parent repository. The child code is not copied into the parent history. Instead, the parent tracks one specific revision of the child.
When someone clones the parent repository, they should use:
If they already cloned without that flag, they can initialize everything afterward:
Update a Submodule Intentionally
A submodule does not automatically follow the latest branch tip. Updating it is a deliberate change to the parent repository.
This explicit pointer update is a feature, not a bug. It makes builds reproducible because the parent repository always records exactly which child revision it expects.
Use Git Subtree for Easier Cloning
If your team dislikes the extra setup that comes with submodules, git subtree can be easier operationally. With subtree, the child repository content is copied into the parent repository history.
To pull later updates:
The advantage is that a normal clone of the parent repository contains everything. The tradeoff is that the parent now vendors the child code instead of referencing it externally.
Prefer a Monorepo When the Split Is Artificial
Sometimes the desire for nested repositories is really a symptom of over-separating a codebase. If the same team owns both sides, changes must be atomic, and release cadence is shared, then one repository with clearly named folders is simpler.
For example, a monorepo might look like this:
That keeps code organization without introducing submodule workflows or split release management.
Configure GitHub and CI to Match the Model
If you choose submodules, your automation must check them out. In GitHub Actions, enable submodule checkout explicitly.
Also pay attention to the submodule URL. HTTPS is often easier for CI because it avoids SSH key setup. Whatever workflow you choose, document clone and update steps in the README so new contributors do not see empty child directories and assume something is broken.
Common Pitfalls
The biggest mistake is treating a raw nested .git directory as if GitHub will manage it automatically. It will not. The parent repository may ignore that folder in unexpected ways, and collaborators will have no standard instructions for cloning it.
Another common issue is forgetting that submodules store commit pointers, not branch subscriptions. Pulling new commits in the child repository does nothing for the parent until the parent stages and commits the new pointer.
Teams also overuse submodules when they actually need monorepo-style atomic changes. If every feature touches both repositories together, the nesting boundary is likely working against the team rather than helping it.
Summary
- GitHub nested repositories are usually implemented with submodules or subtree, not with an unmanaged inner
.gitdirectory. - Use a submodule when the child project has its own lifecycle and should stay independently versioned.
- Use subtree when you want a simpler clone experience and are willing to vendor child content.
- Use a monorepo when both codebases change together and do not need separate release boundaries.
- Document the chosen workflow so local development and CI behave the same way.

