Skip to content

@powersync/react-native@2.1.0 has an unsatisfiable peer: shared-internals@1.1.1 pins @powersync/common to exactly 2.0.0 #1083

Description

@icole

Summary

@powersync/react-native@2.1.0 cannot have its dependency set satisfied by any published version of @powersync/shared-internals.

@powersync/react-native@2.1.0
├── @powersync/common@2.1.0            (exact)
├── @powersync/react@2.0.0             (exact)
└── @powersync/shared-internals@1.1.1  (exact)
     └── peerDependencies: { "@powersync/common": "2.0.0" }   ← exact pin, not a range

shared-internals@1.1.1 requires exactly common@2.0.0, and react-native@2.1.0 brings common@2.1.0. 1.1.1 is the newest published shared-internals and the only version that declares the peer at all — 1.0.0, 1.0.1 and 1.1.0 declare no peerDependencies — so there is no version that satisfies common@2.1.0.

react-native@2.0.2 is self-consistent (common@2.0.0 + shared-internals@1.1.1). This broke in 2.1.0, published 2026-08-13.

Reproduction

mkdir repro && cd repro && npm init -y
npm install @powersync/react-native@2.1.0
npm ls @powersync/common

Why this is more than a warning

pnpm warns and produces a sound tree with one copy:

 WARN  Issues with peer dependencies found
└─┬ @powersync/react-native 2.1.0
  └─┬ @powersync/shared-internals 1.1.1
    └── ✕ unmet peer @powersync/common@2.0.0: found 2.1.0

npm cannot, and which unsound tree you get depends on whether your own package.json happens to declare @powersync/common. Measured on npm 10.9.8, node 22.12.0:

Root declares @powersync/common Result
"2.1.0" or "^2.0.0" one copy at 2.1.0; the peer is left marked invalid and npm ls exits ELSPROBLEMS
not declared two copies of @powersync/common2.0.0 hoisted, 2.1.0 nested under @powersync/react-native
$ npm install @powersync/react-native@2.1.0     # no direct common dependency
$ find node_modules -path '*@powersync/common/package.json'
node_modules/@powersync/common/package.json                                  # 2.0.0
node_modules/@powersync/react-native/node_modules/@powersync/common/package.json   # 2.1.0

The second row is the concerning one, and it is the default for anyone who just installs the RN SDK without also naming @powersync/common themselves. Two copies of the SDK core in one bundle is a correctness problem rather than a size one: the sync engine holds state, so two module instances mean two of it, with two connection lifecycles over a single SQLite database, and instanceof checks and any module-level registry stop agreeing across the boundary. It would present as sync misbehaviour a long way from the install that caused it.

The first row is not fine either — it is just quieter. The tree is knowingly invalid, and it only comes out that way because an unrelated direct dependency happened to pull the hoist in the right direction.

Root cause, and it looks like it is already fixed

This appears to be a workspace: protocol slip rather than a deliberate pin.

  • [Fix] @powersync/shared-internals should have @powersync/common as peer dependency #1061 (merged 2026-08-04) moved @powersync/common from devDependencies into peerDependencies as "workspace:*". The PR description proposes '^2.0.0', but workspace:* publishes as the exact current version, so shared-internals@1.1.1 shipped "2.0.0". Harmless at the time, since react-native@2.0.2 also depended on common@2.0.0.
  • Maintenance items and release fixes #1067 (merged 2026-08-13 11:35 UTC) changed it to "workspace:^2.0.0" — a range. That is the fix.
  • react-native@2.1.0 and common@2.1.0 were published 2026-08-13 13:24 UTC, about an hour and fifty minutes after that fix merged, but from an already-cut release — so they shipped against shared-internals@1.1.1 and the defect went live.
  • On main today the peer reads "workspace:^2.1.0", and the pending Changesets release PR (Version Packages #1075) lists @powersync/shared-internals@1.2.0 and @powersync/common@2.2.0, which should resolve cleanly.

So the ask here is mostly: is a release carrying shared-internals@1.2.0 close? Until one lands, @powersync/react-native@2.1.0 is the current latest and every npm user installing it gets a duplicated core. If a release is not imminent, publishing a shared-internals@1.1.2 with just the widened peer range would fix 2.1.0 retroactively, since the dependency is an exact pin on 1.1.1... though that would need react-native to move to 1.1.2 as well, so a full release is probably simpler.

Filing it because the npm behaviour is silent and a duplicated sync engine is an expensive thing to debug from the symptoms.

Versions

Package Version Relevant field
@powersync/react-native 2.1.0 (latest) deps: common@2.1.0, react@2.0.0, shared-internals@1.1.1
@powersync/shared-internals 1.1.1 (latest) peer: @powersync/common": "2.0.0"
@powersync/common 2.1.0 (latest)

Reproduced with npm 10.9.8 and pnpm 9.4.0 on node 22.12.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions