Skip to content

fix: Mark react-native-nitro-modules peer dependency as optional - #20

Merged
mrousavy merged 1 commit into
masterfrom
fix/optional-nitro-peer
Aug 20, 2026
Merged

fix: Mark react-native-nitro-modules peer dependency as optional#20
mrousavy merged 1 commit into
masterfrom
fix/optional-nitro-peer

Conversation

@mrousavy

Copy link
Copy Markdown
Owner

Problem

Semver ranges never match pre-release versions unless a comparator shares the same major.minor.patch tuple and carries a pre-release tag. So the "react-native-nitro-modules": "*" peer range does not match a version like 0.37.0-beta.0:

range 0.36.5 0.37.0-beta.0 0.37.0 0.38.0-beta.0
* yes no yes no
>=0.0.0-0 yes no yes no
>=0.37.0-0 no yes yes no

Because the peer is required, bun satisfies it itself by installing a second, stable copy of react-native-nitro-modules nested inside this library. An app testing a Nitro pre-release then builds native against the pre-release while Metro bundles the stable JS, and Nitro throws at startup:

Nitro was installed twice: once with native version 0.37.0-beta.0 and once with JS version 0.36.5.

Builds stay green - only runtime catches it.

Fix

Mark the peer optional, so the consuming app is the sole decider of the Nitro version. No range can express "anything, including future pre-releases" (>=0.37.0-0 just moves the breakage to 0.38.0-beta.0), so this has to be resolution behaviour rather than a cleverer range.

"peerDependenciesMeta": {
  "react-native-nitro-modules": { "optional": true }
}

Upstream fix in the Nitro template + docs: margelo/nitro#1516

Trade-off

optional: true also suppresses the missing peer warning. Acceptable: a Nitro Module without react-native-nitro-modules fails loudly at build time (autolinking cannot find the pod / Gradle project), and version mismatches are caught by Nitro's runtime guard - strictly stronger than an install-time range check.

The example app declares react-native-nitro-modules directly, so it is unaffected.

Note

The bun.lock diff also syncs a stale workspace version field that had drifted from package.json (pre-existing; any bun i produces it).

Semver ranges never match pre-releases, so a required peer of "*" does
not match e.g. 0.37.0-beta.0. Package managers then install a second,
stable copy of Nitro next to the pre-release, and the native/JS version
guard throws "Nitro was installed twice" at runtime.

Marking the peer optional leaves the consuming app in full control of
the installed Nitro version.
@mrousavy
mrousavy merged commit a6656b3 into master Aug 20, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant