Git Submodules and Dependencies: Manage Projects Like a Pro
Learn how to use Git submodules to include external repositories within your own. Master submodule management for better project dependencies and organization.

Previously in this course, we explored Git Hooks Basics to automate quality control. In this lesson, we shift our focus to external project management by learning how to use git submodules to incorporate other repositories into your main project.
In large-scale development, you often rely on external libraries or shared components. While language-specific managers like npm (see Managing Dependencies: npm install and package.json Explained) are great for code packages, Git submodules allow you to keep a specific version of an external Git repository inside your own, essentially nesting one repository within another.
Understanding Git Submodules from First Principles
A Git submodule is a repository embedded inside another repository at a specific path. Crucially, the parent repository does not contain the files of the submodule; instead, it stores a pointer to a specific commit hash in the submodule’s repository.
This provides two major benefits:
- Version Pinning: You decide exactly which version of the external code your project uses.
- Independence: The external project remains its own repository, allowing you to pull upstream updates independently.
Adding a Submodule
Let’s advance our running task manager project by adding a common UI library as a submodule. To add a repository, use the git submodule add command followed by the repository URL.
Bash# Add an external UI library as a submodule in the 'libs' folder git submodule add https://github.com/example/ui-kit.git libs/ui-kit
When you run this, Git does three things:
- It clones the remote repository into
libs/ui-kit. - It creates a
.gitmodulesfile in your root directory, which maps the submodule path to its URL. - It adds the submodule directory to your index (stage it and commit it).
Bashgit add .gitmodules libs/ui-kit git commit -m "Add ui-kit as a submodule"
Initializing and Updating Submodules
When you (or a teammate) clone a repository that contains submodules, those folders will initially appear empty. You must initialize and update them to fetch the content.
To pull in the submodule contents after a fresh clone:
Bashgit submodule update --init --recursive
If the external project has been updated and you want to pull the latest changes into your submodule, navigate into the submodule folder and pull:
Bashcd libs/ui-kit git pull origin main cd ../.. # Now, record the new commit hash in the parent repository git add libs/ui-kit git commit -m "Update ui-kit to latest version"
Hands-on Exercise
- Pick an external repository (or use a test repository) and add it as a submodule to your current project under a folder named
vendor/. - Run
git statusand notice how the submodule appears as a directory entry. - Commit the changes and verify that the
.gitmodulesfile is present. - Try to "update" the submodule by changing the commit it points to.
Common Pitfalls
- Forgetting to update: The most common mistake is cloning a repo and forgetting to run
git submodule update --init. You'll end up with empty directories. - Detached HEAD: When you enter a submodule directory, you are often in a "detached HEAD" state. This is normal! You are checked out to the specific commit hash recorded by the parent, not necessarily the latest tip of the branch.
- Nested Complexity: Avoid over-nesting submodules (submodules within submodules). It makes project management difficult and increases the likelihood of "broken" states if one link in the chain is misconfigured.
FAQ
Q: Why use submodules instead of just copying the files? A: Submodules allow you to easily pull updates from the upstream repository without manually overwriting files. It keeps the history of both projects separate but linked.
Q: Are submodules the same as npm or pip dependencies?
A: No. npm and pip manage packages (code artifacts). Submodules manage source control (entire Git repositories). Use packages for code you consume; use submodules for code you might occasionally modify or track closely.
Q: How do I remove a submodule?
A: It's a bit involved: you must remove the entry from .gitmodules, remove the directory from git, and delete the hidden .git/modules/<name> folder. Always double-check your .gitmodules file after removal.
Recap
We learned that Git submodules provide a powerful way to manage external project dependencies by pinning specific commit hashes. By mastering git submodule add and git submodule update, you can maintain modular architectures while keeping your version history clean and predictable.
Up next: Cherry-Picking Changes — we’ll learn how to move specific commits from one branch to another without merging entire histories.
Work with me

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app — built with FilamentPHP so you can manage everything without touching the database.

Custom WordPress Theme Development
A custom WordPress theme built exactly to your design — fast, clean, and easy to manage. No bloated page builders, no compromises.


