Peer Dependencies on protobuf and Connect
Applies to 1.3.0.
Starting with 1.3.0, the Connectum runtime packages declare @bufbuild/protobuf, @connectrpc/connect and @connectrpc/connect-node as peer dependencies instead of regular dependencies. Your application and every Connectum package now share one copy of each library.
Does this apply to you?
You need to act if any of these is true:
- your
package.jsonpins@bufbuild/protobufbelow2.16.0, or@connectrpc/connect/@connectrpc/connect-nodebelow2.2.0(or outside the2.xline); - you install with Yarn;
- you install with
--legacy-peer-depsor setlegacy-peer-deps=truein.npmrc.
If you use npm 7 or later, pnpm or Bun, and you either do not pin these libraries or pin them inside the ranges below, the upgrade needs no changes: the package manager installs the peers and keeps one copy of each.
Breaking change in a minor release
An installation that worked with 1.2 can fail or warn with 1.3, and an application running on an out-of-range copy stops at createServer(). Under strict Semantic Versioning this is a major change; it ships in 1.3.0 as an explicit exception to Connectum's breaking-changes policy, so that applications get the single-copy fix without waiting for 2.0.
Why it changed
With regular dependencies, an application that pinned its own version of these libraries could end up with a second copy that no tool reported:
- message and service types generated against one copy of
@bufbuild/protobufstopped type-checking against the other (TS2345/TS2322on generated service types); @connectrpc/connect-noderequires one exact@connectrpc/connectversion, so a secondconnectnext to it formed a pair it does not support.
A peer dependency makes the application's copy the only copy, and makes a version outside the supported range visible at install time.
What changed
| Package | Peer dependencies in 1.3.0 |
|---|---|
@connectum/core, @connectum/testing | @bufbuild/protobuf ^2.16.0, @connectrpc/connect ^2.2.0, @connectrpc/connect-node ^2.2.0 |
@connectum/auth, @connectum/events, @connectum/interceptors, @connectum/healthcheck, @connectum/reflection | @connectum/core, @bufbuild/protobuf ^2.16.0, @connectrpc/connect ^2.2.0 |
@connectum/otel, @connectum/test-fixtures | @bufbuild/protobuf ^2.16.0, @connectrpc/connect ^2.2.0 |
@connectum/auth,@connectum/eventsand@connectum/interceptorsnow take@connectum/coreas a peer dependency, so they use your application's@connectum/corerather than a copy of their own.@connectum/interceptorsdepends on@bufbuild/protovalidatedirectly, so the validation engine is installed with it on every package manager.@connectum/cliand@connectum/protoc-gen-catalogare unchanged. They are executables that run at build time and keep their own copies, because@bufbuild/protopluginpins@bufbuild/protobufexactly; the single-copy guarantee does not cover them.
What your package manager does
| Situation | npm 7+ | pnpm | Bun |
|---|---|---|---|
Libraries not listed in your package.json | installed automatically | installed automatically | installed automatically |
| Pins inside the ranges | one shared copy | one shared copy | one shared copy |
| Pin below the range | install fails: ERESOLVE unable to resolve dependency tree | installs your copy and prints Issues with peer dependencies found; pnpm peers check lists unmet peer <library> | installs your copy and prints warn: incorrect peer dependency "<library>@<version>" — but see the note below |
Yarn does not install missing peer dependencies. See Required changes.
Bun can stay silent about an old @bufbuild/protobuf
When your project also contains a tool that brings its own in-range @bufbuild/protobuf — @bufbuild/protoc-gen-es and @connectum/protoc-gen-catalog both do — Bun 1.4 installs a too-old @bufbuild/protobuf pin without a warning. The startup check below catches it.
What happens at startup
Whatever installed your dependencies, createServer() checks the @bufbuild/protobuf, @connectrpc/connect and @connectrpc/connect-node that @connectum/core actually loaded. If one is outside the range above, the server is not created and PeerDependencyVersionError (exported from @connectum/core) is thrown:
PeerDependencyVersionError: @connectum/core loaded peer libraries outside its supported range:
- @bufbuild/protobuf: loaded 2.12.1 (from /app/node_modules/@bufbuild/protobuf), @connectum/core requires ^2.16.0
Generated code and the framework must share one in-range copy of each library; an older copy breaks generated types and Connect at runtime.
Fix: raise your pins to the required ranges (npm install @bufbuild/protobuf@"^2.16.0", or the pnpm / bun / yarn equivalent), or force one in-range version with "overrides" (npm, Bun), pnpm "overrides" or Yarn "resolutions", then reinstall.Lockstep is checked at startup too. @connectrpc/connect-node works only with the exact @connectrpc/connect version it declares, so the check also fails when the connect that connect-node loads is another version, or a different copy than the one @connectum/core loads — a pair Bun and Yarn install without complaint:
- @connectrpc/connect: loaded 2.2.0 (from /app/node_modules/@connectrpc/connect), @connectrpc/[email protected] requires 2.1.2
@connectrpc/connect-node works only with the exact @connectrpc/connect version it declares: keep both on the same version, with a single copy.The check has no switch to turn the failure into a warning: an out-of-range copy breaks generated types and Connect at runtime.
The check understands only an exact version or a caret range ^X.Y.Z with X of 1 or higher. A peer range in any other form, such as >=2.2.0 or ^0.2.0, cannot be evaluated: that library is treated as passing, and no error is reported for it.
It is skipped when the loaded versions cannot be determined:
@connectum/coreis bundled into your application (esbuild,bun build, and similar) — a bundle has no package metadata left to read;- the runtime has no
import.meta.resolve.
In those setups the install-time behavior above is your only signal, so keep the pins in range.
Required changes
- Bring your pins into range, or drop them. Raise
@bufbuild/protobufto^2.16.0and@connectrpc/connect/@connectrpc/connect-nodeto^2.2.0, keepingconnectandconnect-nodeon the same version. Alternatively, remove the pins and let npm, pnpm or Bun install the peers. - Regenerate code with
@bufbuild/protoc-gen-es2.16 or later, so generated code matches the runtime. - On Yarn, declare the libraries yourself, together with
@connectum/corewhen you use@connectum/auth,@connectum/eventsor@connectum/interceptors. - Do not bypass a conflict with
--legacy-peer-depsor--force: that puts the second copy back.
Before and after
Before — a pin below the range, accepted silently by 1.2:
{
"dependencies": {
"@bufbuild/protobuf": "2.12.1",
"@connectrpc/connect": "2.1.2",
"@connectum/core": "^1.2.0"
}
}After — pins inside the ranges, connect and connect-node on the same version:
{
"dependencies": {
"@bufbuild/protobuf": "^2.16.0",
"@connectrpc/connect": "^2.2.0",
"@connectrpc/connect-node": "^2.2.0",
"@connectum/core": "^1.3.0"
}
}On Yarn, install them explicitly:
yarn add @connectum/core @bufbuild/protobuf @connectrpc/connect @connectrpc/connect-nodeVerify the upgrade
Each library must appear once across your application and the runtime @connectum/* packages, and connect must equal the version connect-node requires. Copies nested under @connectum/cli or @connectum/protoc-gen-catalog are expected: those are executables, and the code generator pins its own @bufbuild/protobuf. They do not count as violations:
npm ls @bufbuild/protobuf @connectrpc/connect @connectrpc/connect-nodepnpm why @bufbuild/protobuf
pnpm peers checkbun pm ls --all | grep -E '@bufbuild/protobuf@|@connectrpc/connect(-node)?@'npm ls exits non-zero and marks an entry invalid when a peer range is not met. pnpm peers check must not list @bufbuild/protobuf, @connectrpc/connect or @connectrpc/connect-node. With Bun, a second version of @bufbuild/protobuf nested under @bufbuild/protoplugin belongs to the code generator and is expected; any other second version is not. Then start the service: createServer() must not throw PeerDependencyVersionError. Finally, run your type-check and tests.