Scoped Commits in Monorepos

Learn how to use scopes effectively in monorepo projects. Covers package-based scoping, workspace naming conventions, and how to structure commit messages across packages.

Scoped Commits

Detailed Explanation

Monorepo Commit Scoping

In a monorepo, multiple packages or applications live in a single repository. Scopes become essential for identifying which package is affected by each commit. This enables per-package changelogs, independent versioning, and targeted CI pipelines.

Example Messages

feat(web): add dark mode toggle to settings page
fix(api): resolve memory leak in WebSocket handler
build(shared): upgrade TypeScript to 5.4

Scope Naming Strategies

Package Name as Scope

Use the package directory or npm package name:

packages/
  core/       → scope: core
  cli/        → scope: cli
  web-app/    → scope: web-app
  api-server/ → scope: api-server

Abbreviated Scopes

For long package names, use abbreviations agreed upon by the team:

feat(web): ...     → packages/web-app
fix(api): ...      → packages/api-server
build(sdk): ...    → packages/client-sdk

Cross-Package Changes

When a commit affects multiple packages, you have two options:

  1. Omit the scope if the change is truly cross-cutting:

    build: upgrade Node.js to v20 across all packages
    
  2. List affected packages in the body:

    refactor: standardize error handling
    
    Affected packages: core, api, web
    Replace custom error classes with shared AppError
    from @myorg/core in all server-side packages.
    

Tooling Integration

Tools like lerna, nx, and changesets can use scoped commits to:

  • Generate per-package changelogs
  • Determine which packages need version bumps
  • Trigger package-specific CI pipelines
  • Identify affected packages for selective testing

Use Case

You maintain a monorepo with separate packages for a web frontend, an API server, and a shared utility library. You have fixed a bug in the API server's authentication middleware and need a commit message that clearly identifies which package was modified, so your CI pipeline only runs tests for the affected package.

Try It — Git Commit Message Generator

Open full tool