What is the difference between brew, yarn, and npm? - npm

I was using the react-native package which I installed globally with npm. Now it says at the first line after executing the init command. The following:
Installing react-native from npm...
Consider installing yarn to make this faster: https://yarnpkg.com
So I was checking that website and it looked interesting to me, but I don't exactly know what it would be. At first, I thought that I would need brew to install yarn, so I could yarn to install npm. But now I think that yarn is a replacement of npm. Is that a correct statement?
Why would I like to have so many package managers?
I understand that it's useful for software like Atom or Visual Studio Code to have their own package manager. But for development, I do not see the reason why someone would like to use four different package managers (brew for 'primary software', yarn for npm packages, npm for backend modules and bower for front-end libraries). How can this package manager forest be untangled?

I am not familiar with brew, but I suppose you mean the Homebrew software package management system for macOS.
Then the purpose of each system is:
brew: installation of software, i.e. ready to consume applications like wget.
npm: installation of packages (libraries), i.e. pieces of functionality to help you build your own applications.
yarn: also installation of packages.
Yarn has some advantages over npm, the main two are the speed and the predictability. Yarn reuses the npm's package.json file and doesn't change its structure. Therefore you can run yarn install instead of npm install and theoretically everything will work automatically.
P.S. I agree, https://yarnpkg.com doesn't have enough background on why the hell we need another package management system, but there is a great article which fills that gap.

yarn vs npm
yarn and npm are both manage module installations and dependencies. Yarn was built to address some of the shortcomings of npm.
The biggest advantages of yarn over npm are
Installing packages with yarn is parallelized and so package installation is faster.
package.json can be very loose in terms of version numbers. yarn.lock (similar to npm shirkwrap) locks this down so that two machines with the same package.json always install the exact same packages.
yarn allows you to check why some packages are installed (understand the dependency tree)
Ref: https://www.sitepoint.com/yarn-vs-npm/

Yarn is a JavaScript package manager built by Facebook, Google, Exponent, and Tilde. It is created to remove or overcome the features that lack in npm. In comparison with npm it has
Enhanced Security
Offline mode
Parallel Installation - Therefore, faster installation
Another major difference was the yarn.lock file, but after npm ^5.x.x they provide the package-lock.json file too.
And the commands of yarn works like npm:
# Starting a new project
npm init === yarn init
# Installing all the dependencies of the project
npm install === yarn or yarn install
# Adding a dependency
npm install [package] === yarn add [package] # The package is saved to your package.json immediately.
npm install [package]#[version] === yarn add [package]#[version]
npm install [package]#[tag] === yarn add [package]#[tag]
# Add a dev dependency
npm install [package] --save-dev === yarn add [package] --dev
# Upgrading a dependency
npm update [package] === yarn upgrade [package]
npm update [package]#[version] === yarn upgrade [package]#[version]
npm update [package]#[tag] === yarn upgrade [package]#[tag]
# Removing a dependency
npm uninstall [package] === yarn remove [package]
# View registry information
npm view [package] === yarn info [package]
# List installed packages
npm list === yarn list
npm list --depth === yarn list --depth=0
# Install packages globally
npm install -g [package] === yarn global addb [package]
# Run a defined package script
npm run [script] === yarn run [script]
Refferences
https://www.sitepoint.com/yarn-vs-npm/
https://scotch.io/#brian_kimo/npm-vs-yarn
and the official announcement
https://code.facebook.com/posts/1840075619545360

Yarn is, like NPM, a package manager for Node.JS.
Yarn is built by Facebook.
It's faster and has more features than NPM.
Their main selling points are:
Security With yarn.lock file (similar to NPM's npm-shrinkwrap.json)
all dependencies are locked on the exact version. So, you don't have that “But it works on my machine” struggles anymore. Everyone has the
same versions locked in yarn.lock file
Speed Yarn uses (fast) proxies and (offline) caching to deliver your
modules faster. It also has a LICENSE checker, which checks the
license of all your dependency modules.

Related

how do i add yarn package to react native project installed with npm?

Note: Do guide me if something is missing.
So, I wanted to install a package from https://rnfirebase.io/auth/usage, but I have an npm project. The command on the website has only for yarn. I don't want to add yarn to project because (Is there any harm in using NPM and Yarn in the same project?) it states that it is not recommended.
So, then how do I install it with npm?
You have to use yarn, or you can look for a package that has the functions that you are looking for using npm
You can install it with npm just fine, don't worry. They are all package managers installing npm packages from the same repository. There is no difference in what you are installing or how they are installed. You can get different node_module structures, but for yarn you need config for that.
Yes its not recommended because it generates different lockfiles that will dictate different structures and versions in your node_modules folder. You want multiples devs to have the same "experience". However, lots of JS frameworks will come pre-configured with yarn, like React Native and you just end up having two lockfiles. One for npm and one for yarn. There is no harm in deleting the yarn file and keeping the package-lock. If you delete both, a new lockfile for the package manager you are using will be generated on npm i | yarn i | pnpm anyway.
To install it with npm just use npm i <PACKAGE_NAME> so npm i #react-native-firebase/app.
Here is the npm repo page for that package, https://www.npmjs.com/package/#react-native-firebase/app, notice the install command is npm! Only reason firebase devs only mention yarn is because they are hipsters ;)

npm start install my package, but i'm running my project with yarn start

If I installed some package with NPM it will work and recognize it if I run my project with yarn start instead npm start?
Yes, it will still work after all the required packages are installed.
But you should not switch package Managers like that since you will generate two lock files if you use both to install packages. npm generates the package-lock.json and yarn will generate the yarn.lock file. I recommend you to stay with one or switch completely.
In runtime, it does not make any difference if you use yarn or npm.
npm run start and yarn start will do exactly the same.

What is the difference between "npm install" and "npm ci"?

I'm working with continuous integration and discovered the npm ci command.
I can't figure what the advantages are of using this command for my workflow.
Is it faster? Does it make the test harder, okay, and after?
From the official documentation for npm ci:
In short, the main differences between using npm install and npm ci are:
The project must have an existing package-lock.json or npm-shrinkwrap.json.
If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.
If a node_modules is already present, it will be automatically removed before npm ci begins its install.
It will never write to package.json or any of the package-locks: installs are essentially frozen.
Essentially,
npm install reads package.json to create a list of dependencies and uses package-lock.json to inform which versions of these dependencies to install. If a dependency is not in package-lock.json it will be added by npm install.
npm ci (also known as Clean Install) is meant to be used in automated environments — such as test platforms, continuous integration, and deployment — or, any situation where you want to make sure you're doing a clean install of your dependencies.
It installs dependencies directly from package-lock.json and uses package.json only to validate that there are no mismatched versions. If any dependencies are missing or have incompatible versions, it will throw an error.
Use npm install to add new dependencies, and to update dependencies on a project. Usually, you would use it during development after pulling changes that update the list of dependencies but it may be a good idea to use npm ci in this case.
Use npm ci if you need a deterministic, repeatable build. For example during continuous integration, automated jobs, etc. and when installing dependencies for the first time, instead of npm install.
npm install
Installs a package and all its dependencies.
Dependencies are driven by npm-shrinkwrap.json and package-lock.json (in that order).
without arguments: installs dependencies of a local module.
Can install global packages.
Will install any missing dependencies in node_modules.
It may write to package.json or package-lock.json.
When used with an argument (npm i packagename) it may write to package.json to add or update the dependency.
when used without arguments, (npm i) it may write to package-lock.json to lock down the version of some dependencies if they are not already in this file.
npm ci
Requires at least npm v5.7.1.
Requires package-lock.json or npm-shrinkwrap.json to be present.
Throws an error if dependencies from these two files don't match package.json.
Removes node_modules and install all dependencies at once.
It never writes to package.json or package-lock.json.
Algorithm
While npm ci generates the entire dependency tree from package-lock.json or npm-shrinkwrap.json, npm install updates the contents of node_modules using the following algorithm (source):
load the existing node_modules tree from disk
clone the tree
fetch the package.json and assorted metadata and add it to the clone
walk the clone and add any missing dependencies
dependencies will be added as close to the top as is possible
without breaking any other modules
compare the original tree with the cloned tree and make a list of
actions to take to convert one to the other
execute all of the actions, deepest first
kinds of actions are install, update, remove and move
npm ci will delete any existing node_modules folder and relies on the package-lock.json file to install the specific version of each package. It is significantly faster than npm install because it skips some features. Its clean state install is great for ci/cd pipelines and docker builds! You also use it to install everything all at once and not specific packages.
While everyone else has answered the technical differences none explain in what situations to use both.
You should use them in different situations.
npm install is great for development and in the CI when you want to cache the node_modules directory.
When to use this? You can do this if you are making a package for other people to use (you do NOT include node_modules in such a release). Regarding the caching, be careful, if you plan to support different versions of Node.js remember that node_modules might have to be reinstalled due to differences between the Node.js runtime requirements. If you wish to stick to one version, stick to the latest LTS.
npm ci should be used when you are to test and release a production application (a final product, not to be used by other packages) since it is important that you have the installation be as deterministic as possible, this install will take longer but will ultimately make your application more reliable (you do include node_modules in such a release). Stick with LTS version of Node.js.
npm i and npm ci both utilize the npm cache if it exists, this cache lives normally at ~/.npm.
Also, npm ci respects the package-lock.json file. Unlike npm install, which rewrites the file and always installs new versions.
Bonus: You could mix them depending on how complex you want to make it. On feature branches in git you could cache the node_modules to increase your teams productivity and on the merge request and master branches rely on npm ci for a deterministic outcome.
The documentation you linked had the summary:
In short, the main differences between using npm install and npm ci are:
The project must have an existing package-lock.json or npm-shrinkwrap.json.
If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.
If a node_modules is already present, it will be automatically removed before npm ci begins its install.
It will never write to package.json or any of the package-locks: installs are essentially frozen.
The commands are very similar in functionality however the difference is in the approach taken to install the dependencies specified in your package.json and package-lock.json files.
npm ci performs a clean install of all the dependencies of your app whereas npm install may skip some installations if they already exist on the system. A problem may arise if the version already installed on the system isn't the one your package.json intended to install i.e. the installed version is different from the 'required' version.
Other differences would be that npm ci never touches your package*.json files. It will stop installation and show an error if the dependency versions do not match in the package.json and package-lock.json files.
You can read a much better explanation from the official docs here.
Additionally, you may want to read about package locks here.
It is worth having in mind that light node docker images like alpine do not have Python installed which is a dependency of node-gyp which is used by npm ci.
I think it's a bit opinionated that in order to have npm ci working you need to install Python as dependency in your build.
More info here Docker and npm - gyp ERR! not ok
npm ci - install exactly what is listed in package-lock.json
npm install - without changing any versions in package.json, use package.json to create/update package-lock.json, then install exactly what is listed in package-lock.json
npm update - update package.json packages to latest versions, then use package.json to create/update package-lock.json, then install exactly what is listed in package-lock.json
Or said a different way, npm ci changes 0 package files, npm install changes 1 package file, and npm update changes 2 package files.
It does a clean install, use it in situations where you would delete node_modules and re-run npm i.
I have no idea why some people think it's short for "continuous integration". There is an npm install command that can be run as npm i and an npm clean-install command that can be run as npm ci.
npm install is the command used to install the dependencies listed in a project's package.json file, while npm ci is a command that installs dependencies from a package-lock.json or npm-shrinkwrap.json file. The npm ci command is typically used in continuous integration (CI) environments, where the package-lock.json or npm-shrinkwrap.json file is checked into version control and should not be modified. Because npm ci installs dependencies from a locked file, it is a faster and more reliable way to install dependencies than npm install, which could install different versions of dependencies based on the state of the package.json file.

How to update package.json dependencies when linking from globally installed packages?

I organize my development projects installing globally all the npm packages I need with:
npm -g install [package]
Then I simlink individually the dependencies I need for each project with:
npm link [package]
This way, I have to update manually each package.json file to add the dependency, and when I upgrade the global node_modules I have to go and update all the package.json projects.
For this first issue I tried npm link [package] --save but it doesn't add the dependency to package.json and if I use npm install [package] --save it installs the package locally, thing I don't want.
Is there any way to be able to not have to configure package.json manually and be able to have an updated configuration of package.json from many different projects in a easier way?
Yes you can install npm-check-updates, you can find the install and guide here:
https://www.npmjs.com/package/npm-check-updates
when running 'ncu' on the command-line in your root-folder where your package.json is, it will list the packages that can be updated and by running 'ncu -u' on the command-line it updates all the packages for you.

grunt js installing packages

I'm building a grunt javascript project with grunt, and I have a package.json file that looks something like:
{
... name, author, etc here ...
"dependencies": {
"grunt-html":"0.2.1"
}
}
I can run npm install to install grunt-html and this works just fine. But when I add new dependencies, all developers on the team must know to run npm install again. Is there a way to automatically install any packages that have not yet been installed? Should I just run npm install always to ensure I'm up to date?
Yes npm install is the easiest way IMO. Getting everyone familiar with the other npm commands makes managing deps easier as well. Such as:
npm ls to list out the currently installed modules.
Or the --save flag ie, npm install grunt-html --save to install and insert the package and version into your package.json.
npm prune to remove modules not included in your package.json.
Other ways to manage dependencies are to commit the node_modules folder in your repository to avoid other devs from having to run npm install. Or for more complex projects consider using npm shrinkwrap to lock down dependencies to specific versions: npm shrinkwrap docs.
I have not tried grunt-install-dependencies (https://github.com/ahutchings/grunt-install-dependencies), but it seems this may fullfill your needs. Just add the command install-dependencies as first task within your custom definfed grunt tasts, e.g.
grunt.registerTask('build', [ 'install-dependencies', 'useminPrepare', ... ]);