Repository navigation
Allow usage of pnpm #1207
Description
Activity
There hasn't been any activity on this issue in the past 3 months, so it has been marked as stale and it will be closed automatically if no further activity occurs in the next 7 days.
Reopening, pnpm is something that we'd like to support
Reacted by WarrenBuffering- addedno-stale-botThis issue cannot be marked as stale by stale botThis issue cannot be marked as stale by stale bot
on Dec 6, 2022 Hey, support for pnpm is something i have been working on for a while. I was able to make it work with
initcommand and make project running on iOS and Android. However, since pnpm is using symlinks, I discovered a few pitfalls here.- node_modules structure is different. - there is a need of manual changing the paths in the following files in
androidandiosfolders:
ios/Podfile- path tonative_modulesandroid/app/build.gradle- path tonative_modules.gradleandroid/settings.gradle- path tonative_modules.gradle
The pnpm paths are strongly dependent on installed versions of the dependencies, e.g.
.pnpm/@react-native-community+cli-platform-android@9.3.1/node_modules/@react-native-community/cli-platform-android/native_modules.gradle- there is a need of adding the Metro resolver for symlinks: rnx-kit/metro-resolver-symlinks
- Developer needs to manually run
pod installafter initializing the project - CocoaPods installation fails due to incorrectnative_modulespath inPodfilementioned in 1, but that step can be just skipped ininitwhen using pnpm as package manager.
Another possible solution is creating a
.npmrcfile, addingnode-linker: hoistedinside of it and runningpnpm install, but i think it's missing the point of using pnpm as the node_modules structure will become similar to the one known from yarn and npm.Where to go from there? I think adding all the required steps to make it work to the docs is one of the options, but definitely not the best one.
Reacted by Gabriel Zamai- node_modules structure is different. - there is a need of manual changing the paths in the following files in
Following steps working for me
Added public-hoist-pattern configuration in .npmrc to hoist packages from specific scopes:
.npmrc:public-hoist-pattern[]=*@react-native-community* public-hoist-pattern[]=*@react-native*Also integrated the following changes in metro.config.js:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const path = require('path'); /** * Metro configuration * https://facebook.github.io/metro/docs/configuration * * @type {import('metro-config').MetroConfig} */ const projectRoot = __dirname; const config = { watchFolders: [projectRoot], resolver: { nodeModulesPaths: [path.resolve(projectRoot, 'node_modules')], }, }; module.exports = mergeConfig(getDefaultConfig(__dirname), config);React and React Native versions:
"react": "18.2.0",
"react-native": "0.73.5",It seems that every Gradle command is working fine through the command line. However, when I try to sync from Android Studio, the following error is displayed: 'Missing ExternalProject for:'
Are you saying these changes worked for you @rahulpandey? Or are you still getting the
Missing ExternalProject for:error?For us we had react native working with pnpm without hoisting. With new arch enabled. Then at one point of upgrading to newest RN, it stopped working with the error:
Missing ExternalProject for :However, it works if using gradle from the command line.
Ok, I found the fix for React Native.
Instead of
includeBuild('../node_modules/@react-native/gradle-plugin')you have to do
includeBuild(file("../node_modules/@react-native/gradle-plugin").toPath().toRealPath().toAbsolutePath().toString())then it works in newest Android Studio.
Reacted by Zeyu Jiang, Mike, william_tang, Aaron_Zhou, yungblud, Gabriel Meola, ak-quince and devBaunzReacted by DanielThndr, Gabriel Meola, ak-quince and devBaunzReacted by Shaquib Imdad, Mike, valdioflorio, ak-quince and devBaunzOk, I found the fix for React Native.
Instead of
includeBuild('../node_modules/@react-native/gradle-plugin')you have to do
includeBuild(file("../node_modules/@react-native/gradle-plugin").toPath().toRealPath().toAbsolutePath().toString())then it works in newest Android Studio.
You saved my day!!!!
"@react-native-community/cli": "^13.6.4", "@react-native-community/cli-platform-android": "^13.6.4", "@react-native-community/cli-platform-ios": "^13.6.4", "@react-native/gradle-plugin": "^0.74.86",adding above deps to dev dependencies and then from @bimusiek solution for android studio
pnpm works smoothly no issues so far
Reacted by DeepalReacted by DeepalHi there, hope you're fine.
I'm struggling to run my development environment on iOS:
I'm getting the following error message:
.../node_modules/.pnpm/react-native@0.80.2_@babel+core@7.28.3_@react-native-community+cli@19.1.1_typescript@5._3af7c2724a56ff00268a468b9be1dd98/node_modules/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h:10:10 'jsinspector-modern/cdp/CdpJson.h' file not found
But I noticed that the file existe, because when I click in the import reference It navigates to the file. I think this might be a module resolution.I'm using:
pnpm: 10.14.0, react: 19.1.0, react-native: 0.80.2On Android It's working fine until now
rmit-s3804879-sainathreddy-kodiganti commented
on Sep 17, 2025 More actionsHey @GSFZamai ,
were you able to fix this?
Hey @GSFZamai ,
were you able to fix this?
Hey!
My decision atm was to change the package manager toyarn.- Looks like you have some misconfigured package versions thus pnpm keeps both. Make sure you have one react native version. You can use “resolutions” field in package.jeon to force it. Best, Mike -- Mike Hernas…On 4 Oct 2025 at 10:26 +0200, Qazi Amaan ***@***.***>, wrote: qazi9amaan left a comment (react-native-community/cli#1207) Hey @JDScript @bimusiek — thanks for your earlier suggestions! ***@***.***/gradle-plugin").toPath().toRealPath().toAbsolutePath().toString()) However, I’m still running into an issue. The error now says: Included build ***@***.******@***.******@***.***/gradle-plugin has build path :gradle-plugin which is the same as included build ***@***.***/gradle-plugin Do you happen to know a workaround for this, or a cleaner way to resolve the duplicate gradle-plugin build path issue? — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: ***@***.***>
Works just fine, assuming the following tweaks made:
metro.config.js
const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config"); const path = require("path"); /** * Metro configuration * https://reactnative.dev/docs/metro * Tweaks by @devBaunz * * @type {import('metro-config').MetroConfig} */ const config = { // This means we watch the entire repo (change path accordingly if needed) watchFolders: [path.join(__dirname, "..", "..")], resolver: { nodeModulesPaths: [ // PNPM installs symlink app's node_modules, not workspace one path.resolve(__dirname, "node_modules"), ], // This allows us to work with PNPM unstable_enablePackageExports: true, }, // If you use react-native-reanimated, you might need this // transformer: { // getTransformOptions: async () => ({ // transform: { // experimentalImportSupport: false, // inlineRequires: true, // }, // }), // }, }; module.exports = mergeConfig(getDefaultConfig(__dirname), config);
settings.gradle (optional, if you want to use AndroidStudio directly), thanks to @bimusiek
// NOTE: Handle via node-module paths pluginManagement { includeBuild(file("../node_modules/@react-native/gradle-plugin").toPath().toRealPath().toAbsolutePath().toString()) } plugins { id("com.facebook.react.settings") } extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } rootProject.name = 'YourAppName' include ':app' includeBuild(file("../node_modules/@react-native/gradle-plugin").toPath().toRealPath().toAbsolutePath().toString())
babel.config.js (extra, if you want to use node functionality such as crypto/buffer) (make sure you have the packages as runtime dependancies)
module.exports = { presets: ["module:@react-native/babel-preset"], plugins: [ [ "module-resolver", { root: ["."], alias: { // Node functionality for react-native crypto: "react-native-quick-crypto", "node:crypto": "react-native-quick-crypto", stream: "readable-stream", "node:stream": "readable-stream", buffer: "@craftzdog/react-native-buffer", "node:buffer": "@craftzdog/react-native-buffer", }, }, ], ], };
Another nice change to make if you want a better pnpm experience in monorepo setup:
.npmrc (allows installing per directory with proper dep-management, mainly useful for ci/cd)
legacy-peer-deps=true registry=https://registry.npmjs.org/ link-workspace-packages=true recursive-install=false
Allow the usage on
pnpminstead ofyarnornpm.Perhaps a guide for doing the
initmanually would be helpful until such capability is introduced.