Skip to content

Multi-Package Coordination

Atomic updates across your entire dependency graph. No version mismatch. One PR, fully tested.

Deep Dive

Atomic updates, not partial chaos

Modern npm projects rarely have isolated dependencies. React needs react-dom. Express needs @types/express. Jest needs ts-jest. Updating one without the others creates version mismatch.

Dependabot creates separate PRs for each package. Merge react first, and your build breaks until react-dom catches up. Ovvoc resolves the full dependency graph and updates everything together.

One job. One container. One PR. All changes tested as a unit before anything touches your codebase.

Old way

3 separate PRs, merged one at a time, broken between merges.

Ovvoc

1 atomic PR with all packages, fully tested, safe to merge.

React Dependency Graph

react
18.3.119.1.0
react-dom
18.3.119.1.0
@types/react
18.3.1219.1.0
@types/react-dom
18.3.519.1.0
react-test-renderer
18.3.119.1.0

All updated atomically in a single PR

How It Works

Graph-aware, version-safe

1

Detect

Registry monitor detects related package updates. New React version means react, react-dom, and @types/react all need attention.

2

Resolve Graph

Dependency graph identifies all packages that must be updated together to prevent version mismatch.

3

Atomic Update

All packages updated in a single job, inside a single container. Transforms applied to all affected files.

4

Single PR

One PR with all changes, tested as a unit. No partial updates. No broken intermediary state.

Technical Demo

One diff, five packages

All React ecosystem packages updated in a single commit.

package.json
{
  "dependencies": {
-   "react": "^18.3.1",
-   "react-dom": "^18.3.1",
+   "react": "^19.1.0",
+   "react-dom": "^19.1.0",
    "next": "^15.2.0"
  },
  "devDependencies": {
-   "@types/react": "^18.3.12",
-   "@types/react-dom": "^18.3.5",
+   "@types/react": "^19.1.0",
+   "@types/react-dom": "^19.1.0",
-   "react-test-renderer": "^18.3.1"
+   "react-test-renderer": "^19.1.0"
  }
}

Use Cases

Ecosystems that need coordination

React 18 → 19

react + react-dom + @types/react + @types/react-dom + react-test-renderer all updated together. Concurrent mode changes applied.

Express Ecosystem

express + @types/express + body-parser + cookie-parser + cors all coordinated. Middleware API changes handled as a unit.

Testing Stack

jest + @types/jest + ts-jest + babel-jest updated atomically. Config format changes applied to jest.config.js in one pass.

Dependency Graph

Understanding inter-package relationships

Ovvoc builds a dependency graph from your package.json before planning any updates. This graph captures peer dependencies, bundled dependencies, and known companion packages — the relationships that tools like Dependabot ignore.

The graph knows that react requires react-dom. It knows that @types/express must match your express version. It knows that ts-jest must be compatible with your jest version. These relationships are used to coordinate atomic updates that never leave your project in an inconsistent state.

Peer Dependencies

Packages that declare each other as peer dependencies are always updated together. This prevents the common “peer dependency conflict” that breaks npm install.

Bundled Dependencies

Packages that bundle other packages are tracked. When the parent updates, bundled dependencies are checked for compatibility and updated if needed.

Known Companions

Common package pairs like react + react-dom, @types/* + source packages, and jest + ts-jest are maintained in a companion registry and always coordinated.

Transitive Analysis

When a deep dependency changes its peer requirement, Ovvoc traces the chain back to your direct dependency and coordinates the full update path.

Coordination Strategy

The right PR strategy for each update

Atomic PRs

When packages must be updated together, one PR covers all changes. Used for tightly coupled packages like react + react-dom where a partial update would break the build.

react + react-dom + @types/react

Sequential Updates

When order matters, Ovvoc sequences updates correctly. Type definitions are updated before source packages. Foundation packages before those that depend on them.

@types/node → ts-node → jest

Independent PRs

When packages are truly unrelated, separate PRs allow for easier review and independent merge decisions. No unnecessary coupling between unrelated changes.

lodash | express | chalk

Real Example

React ecosystem update in practice

Consider a React 18 to 19 migration. This involves 5 packages that must move together: react, react-dom, @types/react, @types/react-dom, and react-test-renderer. Updating any one of these without the others creates version conflicts and build failures.

Ovvoc's dependency graph detects all 5 as a coordinated group. Type definitions are updated first to ensure TypeScript compatibility. Then react and react-dom are updated together. Finally, react-test-renderer is updated. All changes land in a single PR, tested as a unit.

The result: one PR, one review, one merge. No broken intermediary state. No “I merged react but forgot react-dom” moments. No frantic Slack messages about CI being red.

Monorepo Support

Workspace-aware multi-package updates

Workspace Detection

Automatic detection of npm workspaces and yarn workspaces from your root package.json. Each workspace is scanned independently for its own dependency tree.

Per-Workspace Scanning

Each workspace gets its own scan pass. Different workspaces can use different versions of the same package, and Ovvoc handles each one according to its own constraints.

Cross-Workspace Consistency

When multiple workspaces share a dependency, Ovvoc checks that versions remain consistent across the monorepo after updates. Inconsistencies are flagged in the report.

Coordinated PRs

Updates that span workspace boundaries are coordinated into a single PR. The shared lockfile is regenerated once after all workspace changes are applied.

Ready to automate your dependency updates?

Start with one repo. See the difference in your first PR.