If you've followed my various projects at all, it's apparent just how much I enjoy working with modular code.
Unfortunately, when you're working with modules and packages it's often a question of which kinds of packages to use. Various packages utilize different package managers, and there's quite a bit of confusion about which managers do what and which you actually need for a project.
Composer, for example, primarily manages PHP projects. NPM primarily manages Node packages - and can even be used to update both Node and NPM under the right circumstances. Bower is used to manage front-end packages and, sadly enough, is installed using NPM.[ref]The irony of using a package manager to install yet another package manager is not lost on me.[/ref]
In general, though, let's talk about Composer and NPM. Both package managers do some things right; they also both do some things horribly wrong.
I like Composer because it turns my PHP applications into new versions of the C# projects I used to work on. Where, when a library was included, you just added a simple reference and the library and its APIs were magically available to you. In the interpreted world of PHP, Composer is comfortably close to dynamic library references.
Unfortunately, managing a Composer-powered project can be a bit tricky. Your [cci]composer.json[/cci] project needs to be set up just right and you have to use a web-based interface to submit to Packagist (the hosted Composer package library). Learning Composer (at least for me) is a bit of trial and error, but it does synchronize nicely with GitHub.
Like GitHub, packages are namespaced, which is a major value add for a large, very active development community.
NPM, however, is not namespaced. Once a package is published to the NPM repository, that name is taken. Forever. Even if the package is unpublished. This leads some developers to publish throwaway packages with marketable names just to park on the registry. I hate that.
Unlike Composer, though, NPM is easily (and primarily) managed through the command line. I can push a new release of a package to both GitHub and the NPM repository with a quick command.
Frankly, the lack of namespacing and utter inability to release old/deprecated packages is a major limitation of NPM, so use it judiciously (and be smart about your names).
On the one hand, some might be tempted to create a new package manager that encapsulates all of the good with none of the bad. Unfortunately, the reason we have so many package managers in the first place is because different developers have different strategies for how they'd fix the problem.
Ask 3 engineers to solve a problem and you'll get four different solutions.
As much as I'd like a concise, singular solution to the problem at hand, there isn't one. Instead, there's an obvious use for each package manager, giving way to a simple way to keep the different requirements of each in check. It also gives a way for each community to embrace and learn from the other's strengths, hopefully making each package manager stronger in the end.