Guide: Accessing & Using Internal Packages (Repo-Based Modules & Submodules)

Purpose

To provide a standardized workflow for accessing and using internal code that is managed as repo-based modules, submodules, or monorepos instead of package registries.

This ensures developers handle shared code consistently, with secure access, correct branching, and minimal duplication.


Scope

  • Applies to shared libraries, boilerplates, or modules stored in Git repos (not published as packages).
  • Covers:
    • Git Submodules (linked repos inside parent).
    • Git Subtrees (vendor code snapshots).
    • Monorepo Workspaces (Nx, Turborepo, Yarn/PNPM Workspaces, Lerna).
  • Used by all developers and tech leads.

Objectives

  • Ensure developers can clone, update, and sync shared repo modules without breaking builds.
  • Define clear rules for versioning and contribution.
  • Reduce code duplication by encouraging reuse via submodules/workspaces.

Step-by-Step Usage

Step 1 – Access & Permissions

  • Request access through Access Request Workflow (Doc 7).
  • Repo must be added to developer’s GitHub/GitLab/Bitbucket account with correct role:
    • Read for consumers.
    • Write/Maintainer for contributors.
  • Confirm access via:
  • git ls-remote git@github.com:org/shared-lib.git

Step 2 – Adding Repo-Based Modules

A. Git Submodules

git submodule add git@github.com:org/shared-lib.git libs/shared-lib
git submodule update --init --recursive
  • Commits are locked to a specific SHA → ensures deterministic builds.

B. Git Subtrees (alternative)

git subtree add --prefix=libs/shared-lib git@github.com:org/shared-lib.git main --squash
  • Creates a snapshot inside repo (less overhead, harder to sync).

C. Monorepo (Nx/Turborepo/Yarn Workspaces)

  • Packages are linked under /packages or /libs.
  • Example package.json:
{"workspaces": ["apps/*","packages/*"]}
  • Consumers import like:
import { Button } from "@org/ui"

Step 3 – Syncing Updates

Submodules

git submodule update --remote --merge
  • Pulls latest changes from default branch.
  • Always commit updated submodule SHA.

Subtrees

git subtree pull --prefix=libs/shared-lib git@github.com:org/shared-lib.git main --squash

Monorepo

  • Run package manager install:
yarn install # or pnpm install
  • Internal dependencies auto-linked.

Step 4 – Versioning & Pinning

  • Submodules: Pin to specific commit SHA.
  • Subtrees: Pin to snapshot commit in logs.
  • Monorepos: Use workspace protocol ("ui-lib": "workspace:^1.2.0").
  • Never track “latest” — creates instability.

Step 5 – Contributing Back

  1. Open PR against the shared repo, not local consumer project.
  2. Update CHANGELOG.md + bump version in shared repo.
  3. After merge:
    • Update consumer project’s submodule/subtree.
    • For monorepo: run yarn workspaces run build to verify changes.

Governance & Standards

  • Ownership: Every shared repo must have a listed maintainer.
  • Branching: Consumers must use main/develop only; no feature branches for submodules.
  • Code Review: PRs must be approved by shared repo maintainers.
  • Deprecation: Deprecated modules must be flagged in README + marked in internal catalog.
  • Security: Access must be revoked when developers roll off (EPIC 7).

Troubleshooting

SymptomLikely CauseFix
Submodule repo emptyForgot --recursiveRun git submodule update --init --recursive
Merge conflicts in submoduleSHA mismatch between teamsReset to agreed commit → re-sync
Subtree pull failsDivergence in historyUse --squash or re-add subtree
Monorepo package not linkingWorkspace misconfigCheck package.json paths & lockfile
Build fails on updateBreaking change in shared repoRollback SHA; check CHANGELOG & migration notes

Do’s & Don’ts

Do’s

  • Always pin versions/commits for reproducibility.
  • Document every update in the consumer repo PR description.
  • Use monorepo workspaces for active, evolving libraries.
  • Keep the shared repo README updated with install & usage guides.

Don’ts

  • Don’t point submodules to developer forks.
  • Don’t track main/HEAD directly in consumer repos.
  • Don’t modify shared repo code inside consumer project → always contribute back upstream.
  • Don’t duplicate modules across projects — enforce reuse.