Command Palette

Search for a command to run...

Hectal
PHASE 6Advanced ~14 min· topic 4 of 5

Topic 6.4

Submodules & Monorepos: When Each Makes Sense

In one line

A submodule embeds one Git repository inside another at a specific pinned commit; a monorepo instead keeps multiple projects together in one single repository — two opposite answers to 'how do I manage related codebases,' each with real trade-offs.

0/5 · 0%

Think of it like this

A submodule is like referencing a specific, exact edition of a reference book inside your own book's bibliography — you point at precisely one fixed version, and updating your reference is a deliberate, separate act. A monorepo is like binding several related books into one single volume from the start — one shared cover, one shared index, everything physically together.

Key ideas

  1. 01

    A GIT SUBMODULE (git submodule add <url> <path>) embeds another repository inside yours at a specific PATH, pinned to one exact commit — your repository records which commit of the submodule it depends on, but the submodule's own history and commits remain entirely separate, in their own repository.

  2. 02

    Cloning a repository with submodules requires an extra step — git clone --recurse-submodules <url> (or git submodule update --init --recursive after a plain clone) — since a normal clone does NOT automatically download submodule content, only the pointer recording which commit it's pinned to. Forgetting this step is a genuinely common source of 'why are these folders empty' confusion.

  3. 03

    A MONOREPO takes the opposite approach entirely: multiple distinct projects (perhaps a frontend, a backend, and a shared library) live together in ONE single repository, sharing one commit history, one set of branches, and typically one set of CI pipelines — a single commit CAN atomically change code across multiple projects at once, which is impossible by definition with separate repositories (submoduled or not).

  4. 04

    Submodules genuinely fit when you need to depend on an EXTERNAL project's exact, specific version (a shared library maintained by a different team, or a truly independent open-source dependency) without wanting its full, independent history mixed into yours. Monorepos fit when several projects are developed TOGETHER, by the same team, and genuinely benefit from atomic cross-project commits and unified tooling.

  5. 05

    Submodules have a real reputation for being genuinely fiddly in practice — the extra clone step, needing to explicitly git submodule update after a submodule's pinned commit changes, and easily forgetting either — which is exactly why many teams facing a similar problem choose a monorepo (or a proper package manager / artifact registry, publishing a REAL versioned package instead of a submodule) rather than submodules specifically.

Code & diagrams

SubmoduleVsMonorepodiagram

A submodule pins one external commit by reference; a monorepo just holds everything together directly.

Rendering diagram…
submodules.shmarkdown

Both the addition and the easy-to-forget clone/update steps.

cd ~/scratch/my-first-repo

# Add another repository as a submodule at a specific path
git submodule add https://github.com/example/shared-lib.git libs/shared-lib
git commit -m "Add shared-lib as a submodule"
# Your repo now records shared-lib's URL and its exact pinned commit

# Cloning a repo WITH submodules — the step people forget
git clone --recurse-submodules https://github.com/you/my-first-repo.git
# or, after a plain clone that skipped this:
git submodule update --init --recursive

# Updating a submodule to a newer commit is a deliberate, separate act
cd libs/shared-lib
git pull origin main
cd ../..
git add libs/shared-lib
git commit -m "Bump shared-lib to latest main"
# your repo now pins a NEW exact commit of the submodule

Explain it without notes

01

What exactly does a repository 'remember' about a submodule, versus what lives in the submodule's own separate repository?

02

You're deciding between splitting a frontend and backend into separate repos with a submodule link, or keeping them together in one monorepo. What's the key question that should drive this decision?

Practice

01

Add any small public repository as a submodule to a test repo, commit it, then delete the local clone entirely and re-clone with --recurse-submodules to see the difference versus a plain clone.

02

For a hypothetical frontend + backend project you're familiar with, decide whether a monorepo or separate repositories would genuinely fit better, and write one sentence explaining the reasoning.

Trade-offs

  • ↔

    Submodules give precise, explicit version pinning of an external dependency's exact source, but add genuine day-to-day friction (the extra clone step, manually updating pinned commits) that trips up even experienced developers regularly — a monorepo removes that friction for projects developed together, at the cost of a potentially very large repository and the need for more sophisticated build tooling to avoid rebuilding/retesting everything on every single change.

Done when you can

  • I understand what a submodule actually stores versus what lives in its own separate repository.

  • I know cloning a repo with submodules requires an extra step, and why.

  • I can reason about whether a monorepo or separate repositories genuinely fits a given situation.