Git Submodules as a Package Manager: Why They're So Painful

Git Submodules as a Package Manager: Why They're So Painful

Git submodules are often compared to a package manager, but they fall short in many ways. This article examines the gaps: resolution relies solely on URLs, installation leaves checkouts empty or dirty, storage duplicates objects across worktrees and nested submodules, and updating only supports branch-following. Security vulnerabilities have repeatedly exploited submodule parsing. The author argues that submodules expose git's internals directly, lacking the abstraction and convenience of dedicated package managers.

Most of the pieces are there and the behaviour roughly matches, but they don’t quite line up and the experience of using them is worse at almost every step.
  1. unqueued

    FYI A submodule doesn't have to use a gitfile and a corresponding `$GIT_DIR/modules/<name>` and there are good reasons not to. As long as the submodule has a '.git' it can be a symlink, or regular .git directory for a self contained embedded repo. You can still use the same gitlink in the parent repo representing it's commit id and git will still manage it.

    If I have a 20GB submodule I'd usually just do a `git clone <url> <path> && git submodule add <path>` and it will be treated the same by git. But now I can just delete it and it's purged. And it is more portable less fragile in some ways because it's not de-referencing a gitfile. I prefer my repos to be more bottom-heavy and to not clog my modules folder.

    I have a rough script that's the inverse of `git submodule absorbgitdirs` but it's a bit fragile.

    It would be cool if there was some plumbing to expose this a bit more.

  2. dissent

    If you can point a package manager at a git repo and use it like package, this is accidental convenience. Source code repositories should be factored as source code, with a build step to transform them into packages. For some languages that means compilation, for others it means transpiling, minifying, or just copying files. The resulting artifact is a different shape, designed for consumption.

    If you use git for packages, then your repo becomes the package boundary. You no longer have the option of producing multiple packages from one repo, or even one package from multiple repos.

  3. AlphaSite

    I know it sa toy, but if someone gets the bright idea to do this for real: please learn from npm and dont duplicate packages for every clone of a project. Share them between projects like every sane package manager.

  4. Myrmornis

    A lot of the confusion and criticism surrounding submodules comes from people not understanding that you do not need to learn a lot of new commands to use them: you just cd into the submodule and use it as a normal git repo. Then you cd out and commit the submodule hash change if that's what you want to do.

    Some things are annoying, like removing them. But in general they're extremely useful and designed basically exactly how you'd want: it's extremely consistent since to a good approximation, a submodule behaves the same as a normal git repo once you're inside it.

  5. orliesaurus

    I just have a feeling the developer-experience wouldn't be the same - but that's just a temporary issue perhaps?

More from this day

2026-09-05