Bower's law

on erock's blog

Any successful project will start by doing one thing, well, but end up doing many things, poorly.

I like opinionated libraries. When a library isn't opinionated, they become a reflection of the wants and needs of its user-base, which muddles and expands the scope of the project. This is the death knell for every successful project. Library authors need courage to withstand the onslaught of every drive-by developer requesting new features. To be clear, this isn't exclusively a library problem, it also applies to products in general.

It seems like there is a congruence between people requesting features and developers wanting to continue adding features to their codebase. It's a natural fit, but one I fear we need to be constantly aware of when maintaining successful projects.

I've also noticed that when a project first gets announced, as a library author, it's really exciting to have people using it. So much so that you want to make every single consumer happy with it.

Further, when projects become incredibly popular, more features are requested, more edge-cases are hit, and more developers want to get involved.

What's the name for when a project just keeps growing and growing until it buckles under its own weight?

# Bower's law

Feel free to let me know if such a term or concept already exists as I'm currently woefully ignorant.

Any successful project will start by doing one thing, well, but end up doing many things, poorly.

Many successful projects start out small which generally means they do one thing really well. This is often a big selling point when advertising the project. However, with popularity comes more use cases.

As features get implemented over the project's lifespan, it slowly grows a larger API surface area. This starts to create friction when using the project.

This law has recursion:

[...] Then someone else will reinvent the library by doing one thing, well, but end up doing many things, poorly. Repeat.

# Libraries as plugin systems

Any successful library will inevitably become a plugin system.

Whenever a successful library tries to accommodate the preferences of all its user-base, a plugin system is born. On the surface, engineers love building plugin systems; it's the ultimate abstraction. The library turns into a "platform." Is there anything more self-indulgent than trying to build a platform? It's about as self-indulgent as naming a "law" after yourself.

I know I've fallen into this seductive trap many times and will continue.

eslint, babel, and webpack1 are plugin systems that try to embody the wants and needs of every user preference ... but why? What benefit does that serve? I don't want to install a project that accommodates the wants and needs of every user request; I want them to accommodate my needs. I want a library to satisfy my minimally viable use-case and little more.

I guess we could argue in some cases that a plugin system is great for that because the end-developer can just install the plugins they want to meet their needs. But with that comes overhead.

So, instead of the core functional system being inlined it's also abstracted into a set of plugins. Now what is the core feature of the library? It does nothing besides load and manage plugins. Then every plugin becomes its own "library" and now every project that uses the plugin system needs to install N additional libraries. What a configurable mess. Then someone tries to bundle these plugins together into one "opinionated library" and now I'm spinning and want to throw up.

This is why I really like opinionated libraries, such as rome and esbuild. They definitely have their limitations, but I think the more porous nature of eslint or webpack, where every user preference can be expressed through configuration, is enabling the worst qualities in developers.

This probably sounds harsh, but it was a tough lesson I learned late in life: users don't actually know what they want. It's our job as library developers to stamp our vision into projects. It's imperative for the longevity of a project to be opinionated about the scope of a project. We have to be willing to say no to feature requests. We have to be willing to say that a project is "feature complete" and mean it.


  1. To be clear, all of these projects are monumental and I have nothing but admiration for the maintainers and contributors of these projects. ↩︎

Have a comment? Start a discussion by sending an email to my public inbox.