Yarn: [Question] How to prevent people from using `npm install <package name>`

Created on 10 Nov 2017  路  9Comments  路  Source: yarnpkg/yarn

By digging the issues I found

  "scripts": {
    "preinstall": "node -e \"if(process.env.npm_execpath.indexOf('yarn') === -1) throw new Error('You must use Yarn to install, not NPM')\""
  },

to prevent people from running npm install

But this line fails to prevent people from running npm install <package name>

Is there any way to prevent people from running npm install <package name>?

triaged

Most helpful comment

Hi. There's a way to do this already. You add a fake engine version like so in package.json:

  "engines": {
    "npm": "please-use-yarn",
    "yarn": ">= 1.17.3",
    "node": ">= 12.5.0"
  }

Then you add an .npmrc file to the project root with this:

engine-strict = true

Running NPM then raises an error:

npm ERR! code ENOTSUP
npm ERR! notsup Unsupported engine for root@: wanted: {"npm":"please-use-yarn","yarn":">= 1.17.3","node":">= 12.5.0"} (current: {"node":"12.9.1","npm":"6.10.2"})
npm ERR! notsup Not compatible with your version of node/npm: root@

All 9 comments

Thanks! You are right, npm install <package> --save still works, which is a bummer. And I couldn't find any trick (life-cycle callback, npmrc, ...) to convice npm to disallow installation of new packages; but a _git_ pre-commit hooks might be a solution.

I've made this small change to have a "cleaner" package.json file:

package.json:

  "scripts": {
    "preinstall": "node tools/preinstall-script.js"
  }

tools/preinstall-script.js:

/**
 * Do NOT allow using `npm` as package manager.
 */
if (process.env.npm_execpath.indexOf('yarn') === -1) {
  console.error('You must use Yarn to install dependencies:');
  console.error('  $ yarn install');
  process.exit(1);
}

EDIT: Just found this in AMP: https://github.com/ampproject/amphtml/blob/master/build-system/check-package-manager.js

@SchnWalter I believe the preinstall trick above would also make it impossible for a user to install _your_ package with npm, no?

As a dependency? I'm not sure. I'm not using this for public projects/libraries that someone would require as a dependency.

Hi. There's a way to do this already. You add a fake engine version like so in package.json:

  "engines": {
    "npm": "please-use-yarn",
    "yarn": ">= 1.17.3",
    "node": ">= 12.5.0"
  }

Then you add an .npmrc file to the project root with this:

engine-strict = true

Running NPM then raises an error:

npm ERR! code ENOTSUP
npm ERR! notsup Unsupported engine for root@: wanted: {"npm":"please-use-yarn","yarn":">= 1.17.3","node":">= 12.5.0"} (current: {"node":"12.9.1","npm":"6.10.2"})
npm ERR! notsup Not compatible with your version of node/npm: root@

Hi. There's a way to do this already. You add a fake engine version like so in package.json:

  "engines": {
    "npm": "please-use-yarn",
    "yarn": ">= 1.17.3",
    "node": ">= 12.5.0"
  }

Then you add an .npmrc file to the project root with this:

engine-strict = true

Running NPM then raises an error:

npm ERR! code ENOTSUP
npm ERR! notsup Unsupported engine for root@: wanted: {"npm":"please-use-yarn","yarn":">= 1.17.3","node":">= 12.5.0"} (current: {"node":"12.9.1","npm":"6.10.2"})
npm ERR! notsup Not compatible with your version of node/npm: root@

It doesn't worked here.

$ npm --version
6.12.0
$ node --version
v12.13.0

Accordingly with npm website engineStrict was removed.

engineStrict
This feature was removed in npm 3.0.0
Prior to npm 3.0.0, this feature was used to treat this package as if the user had set engine-strict. It is no longer used.

@rafaelfesi, that's for package.json, not for the npmrc files, which are used to configure NPM.

And the configuration works for me:

$ cat .npmrc 
engine-strict=true

$ npm install
npm ERR! code ENOTSUP
npm ERR! notsup Unsupported engine for [email protected]: wanted: {"node":"^10.16","npm":"please-use-yarn"} (current: {"node":"10.16.3","npm":"6.13.0"})
...

I think pnpm has released the suitable package for this: only-allow

@hckhanh Neither only-allow nor any other solutions posted here prevent npm install <package-name> unfortunately...

@hckhanh Neither only-allow nor any other solutions posted here prevent npm install <package-name> unfortunately...

You're right actually. My solution doesn't prevent that (though hopefully, the devs suspicions that you should use yarn would already be aroused if they previously tried to do a plain old npm install). I would suggest this is actually a bug in NPM. That operation modifies the lock and package json, so it should check the engine. We should potentially raise that separately.

Was this page helpful?
0 / 5 - 0 ratings