Yarn: Inconsistent `add` and `install` for local and global

Created on 18 Jun 2019  路  19Comments  路  Source: yarnpkg/yarn

What is the current behavior?
Locally:
yarn add - needs a package, adds it.
yarn install - installs all packages.
Globally:
yarn global add - installs all packages.
yarn global install - does not exist.

What is the expected behavior?
Locally:
yarn add - needs a package, adds it.
yarn install - installs all packages.
Globally:
yarn global add - needs a package, adds it.
yarn global install - installs all packages.

Versions:
yarn 1.16.0
node 11.9.0
macOS 10.14.5

All 19 comments

Hi @pvinis,

yarn global install - installs all packages.

This would not be correct. Yarn and npm use install only in a local (project) context.

yarn global add - needs a package, adds it.

I can not reproduce this. Please provide more info.

why do they use install only local? why but global too?

for add, the expected behavior should be the same as local. 'yarn global add' should do nothing. 'yarn global add rxjs' should add rxjs' globally.

does that make sense?

why do they use install only local

Because this command was added to be similar to npm. It installs from a package.json in the current directory.

Yarn has different commands than npm.

ok, but imagine that:

yarn locally works like npm, sure. 'yarn install' takes the lockfile and package and gives you node_modules. awesome.

then imagine we can do exactly the same for consistency, globally. 馃榿

I don't think that we will add that. You just add and remove global packages. There is no yarn or yarn install for global packages.

Also you are not in the same context. You do not normally install global packages by using the mentioned lockfile or package.json. Because this is not an application with a name in package.json, just a node_modules directory with the needed packages.

Also yarn install is the equivalent to yarn and yarn warns (on CI) when you use install which is / was deprecated, especially for adding packages.

Yarn and npm are different.

npm i -g pkg is the equivalent to yarn global add

yarn install is there only for compatibility reasons.

so if I make a change in the global package json, then what? or if I have it in my dotfiles and I need to install on a new machine?

why should I need to go in the global for and do as if it's local, and not just enable the same functionality globally?

This is not how it was meant to work afaik.

There were historic reasons why many still wanted the install command. Because they came from npm and yarn as command was weird for them instead of yarn install. The install command in yarn does not add packages and is only an alias for yarn so there is nothing wrong with this.

I think we have missed each other somewhere. I'll try to explain what I think should be the way things work in a quick way.

locally:
yarn add rxjs - adds rxjs to the local project
yarn - installs locally all the deps based on package.json and yarn.lock

global:
yarn global add rxjs - adds rxjs to the the global packages
yarn global - installs globally all the deps based on the global package.json and yarn.lock

This is not how it was intended.

global add and add already installs packages

There is no good reason for yarn global.

How is

yarn global

compared to

cd ~/.config/yarn/global
yarn
cd

not a good reason?

Anyway, I feel like this is just my opinion and usage against yours at this point, so maybe we can just leave this for a while, and come back to it later, or let more people contribute.

and as a final thought, yarn global add does exactly what yarn global would do. That makes sense right? :p To run yarn global add to just install the global packages?

and as a final thought, yarn global add does exactly what yarn global would do

Not right.

That makes sense right?

Not much imho.

add in general adds and installs only the provided package. yarn installs all from the given yarn.lock or package.json.

I know it doesn't make sense, it was sarcasm, because that's what is does.

Dude! Yes right! here is your proof!
https://asciinema.org/a/253314

  • I remove all the global stuff
  • I go to my home dir
  • I run yarn global add
  • all the global stuff are installed

This is a needed functionality, but it should not be happening using yarn global add. It should instead be yarn global or yarn global install.

Yes?

Well, removing node_modules and then doing add will fill node_modules again so this is expected. Same for local.

Same thing happens with node_modules already there. There is no winning with you, is there?

To come back to your initial issue description:

yarn global install - does not exist.

This is documented and expected. There is no global install

yarn global add - installs all packages.

This might be some bug.

yarn global list
yarn global v1.13.0
info "[email protected]" has binaries:
   - auditjs
   - auditjs-win
info "[email protected]" has binaries:
   - create-react-app
info "[email protected]" has binaries:
   - depcheck
info "[email protected]" has binaries:
   - nexe
info "[email protected]" has binaries:
   - phantomjs
info "[email protected]" has binaries:
   - pnpm
   - pnpx
info "[email protected]" has binaries:
   - snyk
info "[email protected]" has binaries:
   - verdaccio
info "[email protected]" has binaries:
   - website-checks
info "[email protected]" has binaries:
   - yo
   - yo-complete
Done

I guess you mean the part Building fresh packages. This rebuilds the binaries (if needed) and is normal.

Because I get only eslint installed in my case.

success Installed "[email protected]" with binaries:
      - eslint

And after a second try there is nothing rebuilt.

The linking process and rebuilding has to happen.

So far you did not provide a full log which shows the issue that you face.

yarn or yarn install is only meant for the current folder. There is nothing like npm i -g or or yarn global or yarn global install

npm i -g
npm ERR! code ENOLOCAL
npm ERR! Could not install from "" as it does not contain a package.json file.

npm ERR! A complete log of this run can be found in:

So Yarn and npm are consistent here. A global install still does not make much sense.

https://docs.npmjs.com/downloading-and-installing-packages-globally

Yarn is and was meant as a npm alternative, another client with the same but better features, especially offline support, caches, reproducible installs and much more.

Probably related: https://github.com/yarnpkg/yarn/issues/932

But this is not what you probably mean.

I know there is no yarn global and "it's documented". This issue is my request to change this.

Still, from my POV it makes not much sense ;-)

OH GOD man!

I know there is no yarn global and "it's documented". This issue is my request to change this.

I want to change this, not to have npm and yarn consistent. I am talking about consistency between add and install, only for yarn, for local and global.

I'll just wait on this until someone related to yarn chimes it.

Hi. You seemed to have a rather difficult to follow discussion.

I am looking for a way to add all project dependencies globally. I do not want them locally. It seems like @pvinis wants to do the same, and indeed yarn global install is the intuitive command for it. Or yarn global, if yarn is supposed to do it locally.

Consistency is nice, but perhaps this discussion is lacking a use case. Let me give one.

I have a project, that I build using Jenkins and Docker. With Docker you have a different mindset how isolation works. Docker sets you up with a root filesystem that is local to your task. You have no need for local node_modules. With Docker I can have my project toolchains and dependencies installed in these root filesystems and Docker takes care of caching them while there are no changes between builds. Jenkins runs the build steps by mounting the build workspace folder from the host into the Docker container root filesystem at the same path as on the host, and with the same current working directory. This means any local node_modules directories in images are never in right place, or replaced by the workspace that has no node_modules. Instead I need to install the dependencies from packages.json globally to be found regardless what is the path to working directory.

Inspired by this discussion and the https://asciinema.org/a/253314 video @pvinis linked to, I get the idea that maybe I can do something like

yarn --frozen-lockfile --modules-folder /usr/local/lib/node --link-folder /usr/local/bin

The Docker node image has process.config.variables.node_prefix === '/usr/local'.

Doing yarn global --frozen-lockfile (which defaults by node_prefix to --prefix /usr/local) would look nicer.

Was this page helpful?
0 / 5 - 0 ratings