Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions docs/docs/getting-started/how-to-build-a-nitro-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,25 @@ First, you need to create a [Nitro Module](../concepts/nitro-modules) - either b
npm install nitrogen --save-dev
```

Also declare `react-native-nitro-modules` as an **optional peer dependency**, so the app using your library is the one that decides which Nitro version gets installed:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the package README with the optional-peer metadata

The published packages/react-native-nitro-modules/README.md still tells library authors to add only the required "react-native-nitro-modules": "*" peer (lines 25–37). Authors following the npm/GitHub landing-page instructions instead of this Docusaurus page will therefore continue producing packages that trigger the duplicate installation under Bun with a Nitro prerelease, recreating the exact runtime failure this change is intended to prevent.

Useful? React with 👍 / 👎.


```json title="package.json"
{
"peerDependencies": {
"react-native-nitro-modules": "*"
},
"peerDependenciesMeta": {
"react-native-nitro-modules": {
"optional": true
}
}
}
```

:::warning
The `optional` flag matters. Without it, package managers try to satisfy the peer range themselves - and since semver ranges never match pre-releases, `"*"` does **not** match a version like `0.37.0-beta.0`. A user testing a Nitro beta would then get a second, stable copy of `react-native-nitro-modules` installed next to yours, and Nitro throws [`Nitro was installed twice`](../guides/troubleshooting#nitro-was-installed-twice) at runtime. Marking the peer optional stops the package manager from installing Nitro on your behalf.
:::

Then, you need to decide if you want to use Nitro's C++ library directly, or use [nitrogen](../concepts/nitrogen) to generate specs:

<Tabs>
Expand Down
30 changes: 30 additions & 0 deletions docs/docs/guides/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,36 @@ If your app fails to build after installing Nitro or a library powered by Nitro,
</TabItem>
</Tabs>

## Nitro was installed twice

If your app crashes at startup with:

```
Nitro was installed twice: once with native version X and once with JS version Y.
```

...then two different copies of `react-native-nitro-modules` ended up in your project - the native build linked one, and Metro bundled the other.

The most common cause is **installing a Nitro pre-release** (e.g. `0.37.0-beta.0`). Semver ranges never match pre-release versions, so a library declaring `"react-native-nitro-modules": "*"` as a required peer dependency does not consider the beta a match - and your package manager silently installs a second, stable copy inside that library's `node_modules` to satisfy the peer.

To fix it:

1. Check how many copies you have:
```sh
npm ls react-native-nitro-modules
```
2. If a library nests its own copy, ask the library author to mark the peer dependency as [optional](../getting-started/how-to-build-a-nitro-module#11-install-nitro-and-nitrogen).
3. As a workaround until then, force a single version from your app's `package.json`:
```json title="package.json"
{
"overrides": {
"react-native-nitro-modules": "0.37.0-beta.0"
}
Comment on lines +91 to +93

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use an npm-compatible override for the direct dependency

When the app installed the beta normally, npm records a direct dependency such as "react-native-nitro-modules": "^0.37.0-beta.0"; npm 11.4.2 rejects the shown exact-version override before resolution with EOVERRIDE: Override for react-native-nitro-modules@^0.37.0-beta.0 conflicts with direct dependency. Consequently, npm users cannot complete this recovery procedure. Use an override referencing the direct dependency (for example $react-native-nitro-modules) or instruct users to make the direct dependency and override specifications identical.

Useful? React with 👍 / 👎.

}
```
(use `resolutions` instead of `overrides` for Yarn)
4. Delete `node_modules` and reinstall - package managers often leave the stale nested copy on disk even after the lockfile is fixed.

## Runtime error

If your app crashes at runtime, make sure to inspect the native logs.
Expand Down
5 changes: 5 additions & 0 deletions packages/react-native-nitro-test-external/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@
"react-native": "*",
"react-native-nitro-modules": "*"
},
"peerDependenciesMeta": {
"react-native-nitro-modules": {
"optional": true
}
},
"eslintConfig": {
"root": true,
"extends": [
Expand Down
5 changes: 5 additions & 0 deletions packages/react-native-nitro-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@
"react-native-nitro-modules": "*",
"react-native-nitro-test-external": "*"
},
"peerDependenciesMeta": {
"react-native-nitro-modules": {
"optional": true
}
},
"jest": {
"preset": "@react-native/jest-preset",
"modulePathIgnorePatterns": [
Expand Down
5 changes: 5 additions & 0 deletions packages/template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@
"react-native": "*",
"react-native-nitro-modules": "*"
},
"peerDependenciesMeta": {
"react-native-nitro-modules": {
"optional": true
}
},
"eslintConfig": {
"root": true,
"extends": [
Expand Down
Loading