From my (admittedly not super deep) experience with multiple package manager (Maven, Gradle, LuaRocks, Ruby gems, the abominable circus of tools they use the Python environment, ...), I found NPM to be by far the most reliable/easy-to-use tool.
That being said, being the best is not necessarily the end goal when the competition is terrible.
1. There is no way to define deployment tokens per package. If you have an organization and want to deploy via CI/CD this can be problematic. If one token is leaked, it affects all packages
2. You cannot enforce 2FA for accounts in organization. So you also have problems if you don’t use CD.
These two problems could be addressed by the registry, the other’s are more of UX Gaps.
3. It is not easy to verify that a package contains the thing that is checked into source. We make it arguably harder by transpiling, etc.
4. It is not widely known how to use npmignore. Often packages contain unnecessary things like all of their documentation website or big images or tests. There could be better UX around that when you create packages or explore packages. The amount of temporary files published by an author in packages is just crazy.
These are the problems from the top of my head, I am sure that I could come up with more. It doesn’t mean that other package managers are better or that NPM is bad, but there is room for betterment.
How is NPM more reliable or easy to use than rubygems? In my opinion Rubygems (with bundler) was the gold standard, and maybe now Cargo (Rust) or Stackage (Haskell) has stolen its crown.
Python package management is a drama, but I've heard Java developers defend their system, forgot if it was maven or gradle.
My main issue with NPM was belatedly solved when Yarn came out. The whole node_modules thing makes me consider it inferior to the others I mentioned, but I'm not sure it can be called a problem.
My main complaint about npm/yarn is that they keep the library code in the project dir and only keep the exact versions and packages that you are using so every time you switch branch you constantly have to run yarn to get the right package versions unlike with ruby gems where there is a folder outside of the project dir which contains a cache of everything you have downloaded and it all just works after branch switches.
Yarn Plug n Play tries to address this and other problems with node_modules such as heavy and deep trees of dependencies that fill up your computer for each project. It generates a .pnp.js file that tells Yarn where packages are located, so they can effectively be installed once and used in multiple projects.
Well one easy point is that rubygem doesn't allow easy local installations. Heck it doesn't even allow specifying all your dependencies — you have to use Bundler for that.
More anecdotally, I've had bad experiences with upgrades, though admittedly, the fact that Windows support is a second-class citizen in many popular gems might have been part of that.
Enforcing publishing through source control
only is a huge step forward. The current NPM process of allowing anyone with write access to publish a package at will is really insecure. I think that's the most exciting thing I've seen about Pika that NPM lacks.
On the contrary; repositories usually involve many people pushing to them, whereas a package release could be handled by just one person (with maybe one or two for backup).
Plus, what about package signing? If the released version comes directly from the repo, does that mean the final package isn't signed by a maintainer?
From my (admittedly not super deep) experience with multiple package manager (Maven, Gradle, LuaRocks, Ruby gems, the abominable circus of tools they use the Python environment, ...), I found NPM to be by far the most reliable/easy-to-use tool.
That being said, being the best is not necessarily the end goal when the competition is terrible.