When Clean Code isn't clean...
I recently tried to build an application using Node.js and a specific library. I do not want to throw shade at said library or its developer(s) so that library shall not be named. However, one particular of its claims to fame stood out to me and struck me as peculiar:
It takes a much more object-oriented approach than most other [...] libraries [of its kind], making your [...] code significantly tidier and easier to comprehend.
I will not argue against the ability of OOP to produce clean code. I will, however, find it strange that it is literally the second sentence I read on your landing page. It shouldn't be a selling point, it should be the baseline, and it should go without saying. But what I am really at odds with is the implication that clean code is solely a property of OOP - which is simply audacious and false. You take the right tool for the right job; you don't simply try to hit a screw with a hammer.
As it turns out, this library has over a hundred different classes and several hundred type declarations. In fact, they decided to reimplement some of the standard types such as Map
just to give it some additional methods. They provide a standard cache solution, a custom Axios-like HTTP request wrapper, and an enum consisting of hundreds of routes.
What's wrong with that? Theoretically, nothing. Practically, it's overengineered, monolithic, and takes decisions away from me. It's an API wrapper. Why do you need over one hundred classes to build an API wrapper? If I want a cache, I will build a cache. Perhaps their cache doesn't even suit my needs. Now there are hundreds of worthless kilobytes of dependency. They recommend using their non-native Set
to keep track of my custom commands, but I don't even know why I should, and I have a much better idea in mind already, so add another few hundred worthless kilobytes. They facilitate object creation through builders, so dozens of classes have an additional ...Builder
class when the underlying logic hardly warrants it. This isn't Java; POJOs are virtually free. And then, when they really could've improved my DX, they chose to let me multiplex server responses to my distinct components myself. It is, effectively, just a wrapper on top of an API with a bunch of unnecessary clutter. I fail to see how this makes my code cleaner. Clean code in part depends on the established standards, conventions, and practices of the language's community. Thus, this is non-paradigmatic JavaScript, which I will argue is dirtier.
Reading the library's guide, it becomes clear that the team has made a simple decision: They want to be the one-stop-shop for everything a developer seeking to build a bot for their target platform needs. This even extends to the very fundamentals such as installing Node.js, installing Visual Studio Code, and installing a Linter (I really, really hate Linters). I suppose this is fine for absolute beginners, but professionals may feel circumcized by their decisions, much like myself.
Worst of all, these nearly one thousand entries in the sidebar navigation of the library's documentation render it virtually impossible to quickly wrap your head around the architecture. Countless generic types make it difficult to deduce their usage just from declaration files, and the codebase lacks any doc-comments; so I find myself having to tab back and forth between the code editor and browser to scavenge their documentation. Worse yet, they are missing types and I couldn't even build my application without hacking in additional fixes regardless.
In the end, I hated working with this library so much that I chose to write my own proprietary API wrapper. At least I finally devised a solution to easily declare a REST API on the client side, which I likely will extract into a standalone library. What you perceive as clean code may not be what I perceive as clean code. Brandishing such an opinionated claim as the unique selling point of your library as one of the first things I see on your website is just ludicrous.
Subscribe to my newsletter
Read articles from Kiru Sebato directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by