The landscape

Bower is one of most popular packages management tool, especially for frontend assets like Javascript and CSS. Other strong contender are  composer, npm and webpack. But Bower shines in simplicity to get going. Bower itself is installed via npm, there is also a reimplementation in PHP called BowerPHP. We use bower on some products however in my team, Kleine Eule, we found one particular important issue with bower ..

The problem

The main issue we found was that we wanted to track exact version numbers of installed packages. Pin pointing exact version numbers of a package (ex: 1.6.7) allows us to better synchronize production between multiple developers. Further more it allows us to track potential known vulnerabilities in those versions. It also makes the migration to new versions a conscious choice. Ideally of course you do not want to have to manually pin the versions but instead want Bower to do this automatically. There is a pull request attempting to solve this issue, but it didn't attract much attention from core developers. A side benefit lock file, as proposed in the PR, could also help  improve install performance.

The “solution”

We attempted to solve this problem in another manner, using custom resolvers. Custom resolvers are a way to extend bower functionalities. Since it doesn't require integrating to Bower core we would not need the core devs to integrate it. Essentially we wanted to implement the behavior of the  composer.lock file. It allows us to pin point installed versions in a very elegant manner automatically. There is similar a approach in npm called shrinkwrap.

The fail

However as we were looking at how we would want our custom resolver to work, we found out that Bower's core functionalities  are fundamentally broken.

d7d4aab6-733d-11e5-80bf-85e9645b8378

The takeaway

It seems like Bower was designed to be unpredictable and at least for a package management we really need a deterministic system. So essentially Bower is great if you are a single developer that uses FTP for deployment but for all other cases its default behavior is simply broken. Trying to fix this via a custom resolver would mean essentially totally changing its entire behavior.

kthxbye

As a result we, team Kleine Eule, decided to just recommend everyone to ditch Bower and instead to migrate future projects to use npm instead of Bower as the easiest migration path.