Are yarn and npm interchangeable in practice? - npm

I have a project with a package.json file and an install bash script that, among other steps, runs npm install.
I'm thinking of updating the script so that it runs yarn install if yarn is available (to take advantage of yarn's caching, lockfile, etc), and falls back to npm install otherwise. As far as I can tell, all the packages seem to install and work ok either way.
Are yarn and npm interchangeable enough for this to be a viable approach, though? Or are there potential issues that this could lead to? Are we meant to just pick one, or is yarn interchangeable with npm in practice?
(nb. I've read this closely related question, but I'm asking this as a separate question because it's about explicitly supporting both yarn and npm install processes in a project)

Yarn and npm (version >=3.0.0) should be relatively compatible, especially moving from npm to Yarn, because compatibility is one of the stated goals of Yarn. As stated in Migrating from npm:
Yarn can consume the same package.json format as npm, and can install any package from the npm registry.
So, in theory, any package.json that is valid for npm should also work equally well for Yarn. Note that I say that npm v2 is probably less compatible - this is because npm migrated from a nested node_modules structure to a flat layout (which is what Yarn uses). That said, Yarn and npm v3 should produce very similar layouts, because, as stated in the issue I linked:
To a first approximation we should try to be very compatible with the node_modules layout for people who need that compatibility, because it'll be the most likely way to avoid long-tail compatibility problems.
However, you will not be able to take advantage of the Yarn.lock generated by Yarn, because (as the name suggests) it's only supported by Yarn, and npm shrinkwrap is not compatible.
Also, as noted by #RyanZim, older versions of Yarn don't support pre- and post-install hooks, but versions later than v0.16.1 do. If you rely on these hooks, you will need to specify to users that versions greater than v0.16.1 are required.
In summary, as long as you encounter no bugs and only use features that are shared by both package managers, you should have no issues whatsoever.

Related

Did "npm install" become deterministic in npm 7?

Here https://github.blog/2021-02-02-npm-7-is-now-generally-available/
it's said:
The lockfile v2 unlocks the ability to do deterministic and reproducible builds to produce a package tree.
But I wonder is it the default behavior now for npm 7? That is, if there is a package-lock.json will npm install update top-most packages with imprecise versions like ^1.0.0 from package.json or it will always work the same way as yarn does?
If npm install is deterministic now, will I be right if I say that npm ci is mostly an equivalent of
rm -rf node_modules && npm install
with some additional checks?
Short Answer:
Yes!
Longer Answer:
Provided you have a package-lock.json or a yarn.lock file, both npm or yarn, respectively, do yield deterministic results.
One thing to note here is that yarn, using yarn.lock file, however, yields deterministic builds only for a specific version of yarn.
Yarn installs are guaranteed to be deterministic given a single
combination of yarn.lock and Yarn version. It is possible that a different version of Yarn will result in a different tree layout on disk.
Whereas npm's algorithms allow it to yield deterministic results even for different versions of the npm because npm tree building contract is entirely specified by the package-lock.json file.
You can find a more detailed explanation of the two in this Blog

does npm still don't saving anything to speed up the installation of already installed modules?

I know pnpm and yarn reuse modules that we already installed, what, in not updated tutorials that i see, we see that this is something that pnpm and yarn came to fix in npm, which downloaded the modules from the internet every time we install it. This still a thing? Does modern npm save cache or something to speed up installation?
Yes, npm has a cache of package tarballs. It does not download the packages from the internet all the time. In fact, you can verify that by running npm install --offline.
The reason npm is slower than pnpm is because of other reasons:
pnpm uses a content-addressable store. Each file inside the node_modules directory is a hard link to the content-addressable store. This makes pnpm faster and more disk space-efficient.
also, pnpm is running the installation stages separately for every installed package. npm cannot do all these operations concurrently as of the current latest versions (v6 and v7).
There might be other reasons pnpm is faster but these 2 must be the most important ones. npm's cache is not one of the reasons.

Yarn or npm? for installing dependencies in react-native

what should I use to install react-native dependencies? yarn or npm, in my case npm have some problems with some of dependencies.
Sometimes i use npm to install these, but i am still confused to decide which one to use permanently.
Both NPM and Yarn are great tools in managing your project's dependencies. There are a lot of improvements Yarn has over npm from faster speeds and stronger security. Many say that if you are already familiar with NPM that a jump to Yarn isn’t really necessary, especially with the release of version 5. Personally I will favor Yarn over NPM mainly because of the speed. But it all boils down to a matter of preference.
Refer
Refer
yarn is much more faster than npm. furthermore npm is also an impressive option

npm, nix and yarn. Which one is better?

I can see create-react-app has added installation with npx. So it made me curious to check which one is better npm, npx or yarn. Which one is better and which is better to use and why?
I don't see why this got negative votes, not everyone comes with inbuilt knowledge on this stuff right ? and this is the place to ask 😅
npm: installation of packages (libraries), i.e. pieces of functionality to help you build your own applications.
npx: npx is a tool to execute packages without installing the packages.
yarn: also installation of packages. yarn is a replacement for npm that sits on top of the same packages repository.
npx isn't the same as the other two, it is a feature of npm to run packages without installing. As for which one is better between npm and yarn, there isn't a clear "winner" (general rule to apply in life too). I personally prefer yarn since in my experience it was faster and less verbose, another positive was it had a lockfile but now npm has one too (and I hear new versions are faster as well).
tl;dr: Either is fine really.
You can compare the feature of npm and yarn. yarn is faster than npm because it is doing parallel installation and npm is doing serial installation of modules. Previous version of npm does not have lockfile now both npm and yarn have lock file. Both are build on the top of same repository.
npx is totally different from npm and yarn. It is a tool to execute packages without installing it.
So I will suggest yarn if you want to decrease the build time of the application.

What is the difference between npm-shrinkwrap.json and package-lock.json?

With the release of npm#5, it will now write a package-lock.json unless a npm-shrinkwrap.json already exists.
I installed npm#5 globally via:
npm install npm#5 -g
And now, if a npm-shrinkwrap.json is found during:
npm install
a warning will be printed:
npm WARN read-shrinkwrap This version of npm
is compatible with lockfileVersion#1,
but npm-shrinkwrap.json was generated for lockfileVersion#0.
I'll try to do my best with it!
So my take-away is that I should replace the shrinkwrap with the package-lock.json.
Yet why is there a new format for it? What can the package-lock.json do that the npm-shrinkwrap.json cannot?
The files have exactly the same content, but there are a handful of differences in how npm handles them, most of which are noted on the docs pages for package-lock.json and npm-shrinkwrap.json:
package-lock.json is never published to npm, whereas npm-shrinkwrap is by default
package-lock.json files that are not in the top-level package are ignored, but shrinkwrap files belonging to dependencies are respected
npm-shrinkwrap.json is backwards-compatible with npm versions 2, 3, and 4, whereas package-lock.json is only recognized by npm 5+
You can convert an existing package-lock.json to an npm-shrinkwrap.json by running npm shrinkwrap.
Thus:
If you are not publishing your package to npm, the choice between these two files is of little consequence. You may wish to use package-lock.json because it is the default and its name is clearer to npm beginners; alternatively, you may wish to use npm-shrinkwrap.json for backwards compatibility with npm 2-4 if it is difficult for you to ensure everyone on your development team is on npm 5+. (Note that npm 5 was released on 25th May 2017; backwards compatibility will become less and less important the further we get from that date, as most people will eventually upgrade.)
If you are publishing your package to npm, you have a choice between:
using a package-lock.json to record exactly which versions of dependencies you installed, but allowing people installing your package to use any version of the dependencies that is compatible with the version ranges dictated by your package.json, or
using an npm-shrinkwrap.json to guarantee that everyone who installs your package gets exactly the same version of all dependencies
The official view described in the docs is that option 1 should be used for libraries (presumably in order to reduce the amount of package duplication caused when lots of a package's dependencies all depend on slightly different versions of the same secondary dependency), but that option 2 might be reasonable for executables that are going to be installed globally.
Explanation from NPM Developer:
The idea is definitely for package-lock.json to be the Latest and
Greatest in shrinkwrap technology, and npm-shrinkwrap.json to be
reserved for those precious few folks out there who care very much
about their libraries having an exact node_modules -- and for people
who want CI using npm#>=2 to install a particular tree without having
to bump its npm version.
The new lockfile ("package-lock.json") shares basically all of the
same code, the exact same format as npm-shrinkwrap (you can rename
them between one another!). It's also something the community seems to
understand: "it has a lockfile" seems to click so much faster with
people. Finally, having a new file meant that we could have relatively
low-risk backwards-compat with shrinkwrap without having to do weird
things like allow-publication mentioned in the parent post.
I think the idea was to have --save and shrinkwrap happen by default but avoid any potential issues with a shrinkwrap happening where it wasn't wanted. So, they just gave it a new file name to avoid any conflicts. Someone from npm explained it more thoroughly here:
https://www.reddit.com/r/javascript/comments/6dgnnq/npm_v500_released_save_by_default_lockfile_better/di3mjuk/
The relevant quote:
npm publishes most files in your source directory by default, and
people have been publishing shrinkwraps for years. We didn't want to
break compatibility. With --save and shrinkwrap by default, there was
a great risk of it accidentally making it in and propagating through
the registry, and basically render our ability to update deps and
dedupe... null.
So we chose a new name. And we chose a new name kind of all of a
sudden. The new lockfile shares basically all of the same code, the
exact same format
package-lock.json versions are guaranteed with only npm ci (since npm install overwrites package-lock.json if there is a conflict with package.json).
npm-shrinkwrap.json versions are guaranteed with both npm ci and npm install.