[Bug?]: yarn removes custom dependency grouping from `package.json` during `yarn install`
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 8.1k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
Self-service
- I'd be willing to implement a fix
Describe the bug
I have a package.json that I've organised to keep the dependencies grouped (based on keeping the vanilla react-native dependencies separate from our custom ones, to help with upgrading). I've upgraded this to use yarn 3.6.4 and now when I run yarn install (even if the current node_modules is in sync with the yarn.lock, so effectively a no-op) the listings for dependencies and devDependencies are reordered alphabetically, with any manual grouping stripped out.
My expectation is that the package.json file is respected in all ways as much as possible, including formatting, and it feels like this is a regression from previous versions of yarn.
To reproduce
Starting with a package.json like so:
{
"name": "example",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest",
"postinstall": "patch-package"
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.74.2",
"@react-native-async-storage/async-storage": "1.23.1",
"@react-native-community/datetimepicker": "8.0.1",
"@react-native-community/netinfo": "11.3.1",
"@react-navigation/native": "~6.0.13",
"@react-navigation/stack": "~6.3.2",
"Base64": "^1.1.0",
"deprecated-react-native-prop-types": "~4.1.0",
"lodash": "^4.17.15",
"moment": "^2.24.0",
"moment-range": "^4.0.2",
"rc-swipeout": "~2.0.11",
"react-native-animatable": "^1.3.3",
"react-native-blob-util": "~0.18.3",
"react-native-camera": "~4.2.1",
"react-native-draggable-flatlist": "~4.0.1",
"react-native-elements": "~2.1.0",
"react-native-fs": "~2.18.0",
"react-native-gesture-handler": "~2.16.1",
"react-native-image-picker": "2.3.0",
"react-native-keyboard-aware-scroll-view": "~0.9.5",
"react-native-linear-gradient": "^2.5.6",
"react-native-markdown-renderer": "^3.2.8",
"react-native-modal-selector": "~2.0.9",
"react-native-orientation-locker": "1.4.0",
"react-native-pdf": "~6.6.2",
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.1",
"react-native-screens": "3.31.1",
"react-native-signature-capture": "^0.4.10",
"react-native-svg": "15.2.0",
"react-native-svg-charts": "^5.3.0",
"react-native-table-component": "~1.2.2",
"react-native-vector-icons": "~9.2.0",
"react-native-video": "~5.2.1",
"react-native-webview": "13.8.6",
"react-redux": "~7.2.9",
"redux": "^4.0.4",
"redux-persist": "^6.0.0",
"redux-persist-filesystem-storage": "~4.2.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/babel-preset": "0.74.84",
"@react-native/eslint-config": "0.74.84",
"@react-native/metro-config": "0.74.84",
"@react-native/typescript-config": "0.74.84",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.6.3",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-test-renderer": "18.2.0",
"typescript": "5.0.4",
"@babel/plugin-transform-class-properties": "~7.22.5",
"@babel/plugin-transform-private-methods": "~7.22.5",
"@testing-library/jest-native": "^5.4.2",
"@testing-library/react-native": "^7.2.0",
"babel-eslint": "^10.1.0",
"eslint-plugin-react": "^7.20.6",
"eslint-plugin-react-native": "~4.0.0",
"patch-package": "~7.0.0"
},
"engines": {
"node": ">=18"
},
"packageManager": "yarn@3.6.4"
}
run yarn install, which modifies package.json to:
{
"name": "example",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest",
"postinstall": "patch-package"
},
"dependencies": {
"@react-native-async-storage/async-storage": "1.23.1",
"@react-native-community/datetimepicker": "8.0.1",
"@react-native-community/netinfo": "11.3.1",
"@react-navigation/native": "~6.0.13",
"@react-navigation/stack": "~6.3.2",
"Base64": "^1.1.0",
"deprecated-react-native-prop-types": "~4.1.0",
"lodash": "^4.17.15",
"moment": "^2.24.0",
"moment-range": "^4.0.2",
"rc-swipeout": "~2.0.11",
"react": "18.2.0",
"react-native": "0.74.2",
"react-native-animatable": "^1.3.3",
"react-native-blob-util": "~0.18.3",
"react-native-camera": "~4.2.1",
"react-native-draggable-flatlist": "~4.0.1",
"react-native-elements": "~2.1.0",
"react-native-fs": "~2.18.0",
"react-native-gesture-handler": "~2.16.1",
"react-native-image-picker": "2.3.0",
"react-native-keyboard-aware-scroll-view": "~0.9.5",
"react-native-linear-gradient": "^2.5.6",
"react-native-markdown-renderer": "^3.2.8",
"react-native-modal-selector": "~2.0.9",
"react-native-orientation-locker": "1.4.0",
"react-native-pdf": "~6.6.2",
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.1",
"react-native-screens": "3.31.1",
"react-native-signature-capture": "^0.4.10",
"react-native-svg": "15.2.0",
"react-native-svg-charts": "^5.3.0",
"react-native-table-component": "~1.2.2",
"react-native-vector-icons": "~9.2.0",
"react-native-video": "~5.2.1",
"react-native-webview": "13.8.6",
"react-redux": "~7.2.9",
"redux": "^4.0.4",
"redux-persist": "^6.0.0",
"redux-persist-filesystem-storage": "~4.2.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/plugin-transform-class-properties": "~7.22.5",
"@babel/plugin-transform-private-methods": "~7.22.5",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/babel-preset": "0.74.84",
"@react-native/eslint-config": "0.74.84",
"@react-native/metro-config": "0.74.84",
"@react-native/typescript-config": "0.74.84",
"@testing-library/jest-native": "^5.4.2",
"@testing-library/react-native": "^7.2.0",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^29.6.3",
"eslint": "^8.19.0",
"eslint-plugin-react": "^7.20.6",
"eslint-plugin-react-native": "~4.0.0",
"jest": "^29.6.3",
"patch-package": "~7.0.0",
"prettier": "2.8.8",
"react-test-renderer": "18.2.0",
"typescript": "5.0.4"
},
"engines": {
"node": ">=18"
},
"packageManager": "yarn@3.6.4"
}
Environment
System:
OS: macOS 14.5
CPU: (12) arm64 Apple M2 Pro
Binaries:
Node: 18.20.2 - /private/var/folders/_g/kc3wz03n2mb32x9ty7m6sh9m0000gn/T/xfs-0956b883/node
Yarn: 3.6.4 - /private/var/folders/_g/kc3wz03n2mb32x9ty7m6sh9m0000gn/T/xfs-0956b883/yarn
npm: 9.9.3 - /opt/local/bin/npm
npmPackages:
jest: ^29.6.3 => 29.7.0
Additional context
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the behavior with the provided package.json and Yarn 3.6.4 using yarn install, confirming the dependency groups are reordered even when installation is otherwise a no-op. Trace the install path that writes package.json; done means custom dependency ordering and grouping remain unchanged after installation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nodejs, typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100