Skip to content

@nx/expo EAS build fails with PNPM workspaces because Nx doesn't resolve * versions in package.json #35275

@lxup

Description

@lxup

Current Behavior

Inside the apps/mobile/package.json managed by Nx, dependencies are listed with * as their version. Normally, when triggering a build, Nx dynamically synchronizes and resolves these * versions with the actual versions from the root package.json before handing the project over to EAS to compile.

However, when using PNPM workspaces, it seems this replacement (or sync-deps step) does not execute properly or fails silently. As a result, the physical package.json sent to EAS still contains the * versions.

When the EAS build process runs pnpm install --frozen-lockfile, PNPM compares the * ranges in package.json with the strict versions in pnpm-lock.yaml, determines they are out of sync, and immediately crashes the build with an ERR_PNPM_OUTDATED_LOCKFILE error.

Expected Behavior

Nx should successfully replace the * versions in the app-level package.json with the actual semantic versions from the root package.json before EAS attempts to package the app and run pnpm install, regardless of whether PNPM workspaces are enabled or not.

GitHub Repo

No response

Steps to Reproduce

  1. Create an Nx workspace using pnpm with PNPM workspaces enabled (pnpm-workspace.yaml).
  2. Generate an Expo application inside the workspace (@nx/expo:app).
  3. Ensure the app's package.json relies on the * versioning pattern for shared dependencies (default Nx behavior).
  4. Run a local EAS build: pnpm nx run mobile:build --local --clear-cache (if mobile is the name of your app).
  5. The build fails during the EAS [INSTALL_DEPENDENCIES] phase because the packaged package.json still contains *.

Nx Report

NX   Report complete - copy this into the issue template

Node           : 22.22.0
OS             : darwin-arm64
Native Target  : aarch64-macos
npm            : 11.7.0
daemon         : Available

nx (global)            : 22.6.5
nx                     : 22.4.1
@nx/js                 : 22.4.1
@nx/eslint             : 22.4.1
@nx/workspace          : 22.4.1
@nx/jest               : 22.4.1
@nx/detox              : 22.4.1
@nx/devkit             : 22.4.1
@nx/esbuild            : 22.6.5
@nx/eslint-plugin      : 22.4.1
@nx/expo               : 22.4.1
@nx/module-federation  : 22.4.1
@nx/nest               : 22.6.5
@nx/next               : 22.4.1
@nx/node               : 22.4.1
@nx/playwright         : 22.4.1
@nx/react              : 22.4.1
@nx/rollup             : 22.4.1
@nx/vite               : 22.4.1
@nx/vitest             : 22.4.1
@nx/web                : 22.4.1
@nx/webpack            : 22.4.1
@nx/docker             : 22.4.1
typescript             : 5.9.3
---------------------------------------
Registered Plugins:
@nx/webpack/plugin
@nx/eslint/plugin
@nx/jest/plugin
@nx/docker
@nx/next/plugin
@nx/playwright/plugin
@nx/expo/plugin
---------------------------------------
Cache Usage: 13.71 MB / 92.64 GB
---------------------------------------
The following packages should match the installed version of nx
  - @nx/esbuild@22.6.5
  - @nx/nest@22.6.5

To fix this, run `nx migrate nx@22.6.5`
---------------------------------------
⚠️ Multiple Nx versions detected

Your workspace uses nx@22.4.1, but other packages depend on a different version:
  - web-e2e → @nx/devkit → nx@22.6.5

These packages should not have nx as a dependency. Please report this issue to the package maintainers.
Run `npm explain nx@22.6.5` for more details.

Failure Logs

[INSTALL_DEPENDENCIES] ERR_PNPM_OUTDATED_LOCKFILE Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with <ROOT>/apps/mobile/package.json
[INSTALL_DEPENDENCIES] 
[INSTALL_DEPENDENCIES] Note that in CI environments this setting is true by default. If you still need to run install in such cases, use "pnpm install --no-frozen-lockfile"
[INSTALL_DEPENDENCIES] 
[INSTALL_DEPENDENCIES]   Failure reason:
[INSTALL_DEPENDENCIES]   The importer resolution is broken at dependency "eslint-plugin-react-compiler": version "19.1.0-rc.2" doesn't satisfy range "*"

Package Manager Version

pnpm 10.23.0

Operating System

  • macOS
  • Linux
  • Windows
  • Other (Please specify)

Additional Information

The issue stems from the fact that EAS reads the physical package.json file from the disk to bundle it for the build environment. Because Nx fails to overwrite the * with the concrete versions from the root package.json (like it does when PNPM workspaces are NOT used), pnpm install --frozen-lockfile inside the EAS container rightfully panics.

For context, root package.json looks like this:

{
  "dependencies": {
    "@expo/metro-config": "~55.0.11",
    "expo": "~55.0.0",
    "react-native": "0.83.4"
  },
  "devDependencies": {
    "@nx/devkit": "22.4.1",
    "@nx/expo": "22.4.1",
    "@nx/workspace": "22.4.1",
    "eas-cli": "^18.6.0"
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions