DEV Community

Cover image for The hidden cost of “don’t reinvent the wheel”

The hidden cost of “don’t reinvent the wheel”

Stephen Belovarich on February 28, 2020

There’s a catchphrase I’ve heard from the even the most experienced web engineers in the past few years. Don’t reinvent the wheel Mos...
Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

I have to be honest, there is a limit to this creating new things yourself. What you describe above is sounding like poor library choices, no comunity or help should never be an afterthought. Picking a library is like picking a loyal dog, it may be around for years, pick the library on community, support, help and idiomatic styles that do fit your need.

As for code style, there are a just a handful of styles and most derive from imperitive or declarative, but more than this, if the library came with lint, documentation and tests that's a rosetta stone. If all else fails read the source of the library not the minified nasty code, that is the perpose of open source, because it's open for you to read, lastly library authors are often more than happy to answer your questions and take pull requests.

What about lines of code? Okay it's not the size it's how you use it. Bloat comes from redundancy, which we can not know exactly if the lines of code are needed or not. What we can speculate is that the potential is thier to make the code more resilient to cases that you don't need to cover. That is where iterative development comes in, you can take a crappy library to get the functionality today and over time overwrite it.

As a point of pride I personally hate libraries because I am a creative developer with the skills inclination and experience to make a good attempt. But instead of resist that urge and reserve that for my own projects indulge myself when it's appropriate. Why? because I am paid to solve problems, not write code, and if my time is my employers money I better make that money worth while by using off the shelf solutions which are battle tested.

Collapse
 
steveblue profile image
Stephen Belovarich • Edited

I love libraries, don't get me wrong.

I'm not saying don't use a library. I'm saying maybe every time teams have to implement a new feature, it isn't always appropriate to pull something off the shelf. This is not an all or nothing argument.

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Shades of grey don't make very good points, apart from pencils 😂. Thanks for hearing me out.

Collapse
 
puukallistaja profile image
Puukallistaja

Your last paragraph was supposed to be my contribution to the discussion, almost verbatim :)

Maybe it is also a somewhat good analog for writing your own tools. At first you are so happy with your solution. It's elegant, robust and foolproof. But then you discover an edge case that has to be handled. And then business asks for an extra feature. Maybe you are time-pressed, so you take a shortcut in implementation. Then you have to add documentation, because a new developer is joining. In the end of the day (year?), you have duplicated the library you tried to avoid, only slightly worse. And without an OSS community around it.

That said, I wish you all a profession where you can write bleeding edge custom code all day, every day :)

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Many developers come to the same conclusion, I remember a few years back when I would have fully supported the sentiment of this post. Because the ideal is, for a better word, sexy. But one day it hits you, there are hidden wins and ways to achieve your goals that might feel like a sacrifice, but they are a damn sight faster. Fixing up something like a library or wrapping it in abstraction is tantamount to managed risk, we can choose when it is a good time to take action later on in development.

There are one or two exceptions, libraries that are misguided in reimplemented native APIs, which the author failed to check existed, libraries that don't announce self redundancies and libraries that abstract simple tasks that are overengineered, all those cases are things I really don't like.

I myself am a new developer in my job and I can tell you this much, if my predecessor had not chosen to implement a library for core features I would be far more helpless.

Thread Thread
 
steveblue profile image
Stephen Belovarich • Edited

The benefits of libraries are obvious. I don’t think we consider the negatives that can arise from choosing a library enough. It seems like the de facto solution for JavaScript engineers is to install an npm package for everything. There are times the custom solution is more responsible, performant and user friendly than adopting a library. This isn’t just about the ideal of using the latest browser API.

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀 • Edited

I think this issue transcends any language specific developer. This is business driven culture practices (it depends where you work). Although I have never come across a developer who actually pulls in a dependency per ticket, I suppose such a developer might exist.

Your point about consideration, I keep reading over the internet about JavaScript engineers for some reason having been lumped with a hive mind reputation, it just doesn't equate to fact. We are all individuals and just developers. But yes people do use npm. No Npm is NOT a good package manager. One of the reasons why the Deno project exists I suppose?

It comes down to this, you and your team are maybe a handful of people. For instance you want to create a greenfield product that uses typescript, state machine architecture, and JSON schema, you have 6 months to do it. Several epics are created and over that time you expect a couple of new hires to join you. At this point I would install the Typescript compiler, I would not use Deno or write my own because... You can see why and that's a easy one, what about a state machine architecture? Okay this is a tough call, on the one hand overengineering is a real and present threat, xstate is great, tested to death, more so than I could in 12 months of unit and acceptance tests, sure some switch statement would work too but this isn't really my applications focus, plus xstate is well documented and we'll optimised, great for those new hires who will appreciate the autonamy. Okay schema driven forms, let's see, could I impliment this myself? Yes, are there any good solutions that work with typescript or better yet, generate from typescript? I don't know, let's timebox this for maybe 4 hours... 4 hours later (true story) mine mostly works.. the next day, there's a bug here, several weeks and new tests and bugs fixed, I decide to quickly Google a JSON schema form library, oh there are 3, and they are quite well contributed too, I use that, and improve my own so that one day I can atleast compare them.

Thanks for reading and please, we may agree to disagree (somewhat, because I think I agree with you depending on how my day is going 🏠🏚️).

Thread Thread
 
steveblue profile image
Stephen Belovarich • Edited

If a library works and doesn’t negatively effect the production bundle, has a developer friendly API, integrates cleanly with your environments, and has a shallow learning curve go ahead, use it. When there are several options available but none of them provide those things, code your own implementation. Sounds nice but there really aren’t any hard and fast rules. As others have pointed out, it’s case by case. There doesn’t have to be a greenfield project though to implement something custom.

True story. I tried to use a plugin for a thing. It did what I wanted but found a nasty side effect that meant I couldn’t use it. I try another package that does a similar thing, but no way to integrate cleanly. I diagnose the bug and create an issue in the repo, author responds promptly. I dig in deeper while figuring out if I could just submit a pull request. I find a bunch of unnecessary code that would effect performance. Is it worth my time arguing with the author? I took a hour to learn how to develop the plugin and wrote one that did the same thing but with far less code, implementation was more performant. A few minutes later after testing it out, I npm publish and integrate the new plugin with my project. Done in less than two hours. Yes, I’ll be on the hook for maintenance, but there is hardly any to speak of. Oh well. In my opinion, we need more of that kind of mentality in web development, but in my experience engineers with a “can do it” attitude are few and far between.

Collapse
 
dansilcox profile image
Dan Silcox • Edited

I think, as with anything, this is all very contextual. If someone is writing a million custom tools then someone else will have to maintain all those tools. Trust me, this is not a happy place!

I think the reason we have frameworks, off the shelf tooling, etc is so that we as professionals can apply our skills to the problems actually relevant to our domain.

If you work for an online payment company you should be able to focus on things relevant to your business, that provide value, not have to write your own logging framework, build your own CDN and roll your own authentication service.

I totally agree it’s a really useful skill to be able to do these things and you learn a lot through the process, and of course if you reach a stage where the off the shelf version does not fit the purpose and you need something more bespoke, great, apply those skills. But remember that code is as much a liability as an asset. Someone has to maintain it, support it, etc etc.

Collapse
 
jessekphillips profile image
Jesse Phillips

All the programming rules are to help people stick to generally good coding practices. Deciding when to break from tradition requires a higher understanding of why it is their.

You see the same thing in music and writing. Never split an infinitey, except when it works for you.

It becomes challenging if you do know when to break away, then you get more experience and realize you should stick to the rules because most people are trained to follow rules and not to break from them.

Collapse
 
mdamaceno profile image
Marco Damaceno

All languages pass through a maturity process. It happens to javascript right now. Take a look at NPM and search for a package for any purpose. You will see hundreds of packages that do the same thing! Why don't the developers contribute to a single one? Is this "reinvent the wheel"? I think so. The same thing happened to Ruby community with its hundreds of gems. Today, many of them are dead, surviving just that ones really matter.

I don't think using React, Svelte or any other library is a problem. These mentioned libraries came to the playground naturally. They're just tools and solve problems.

It's not about reinventing the wheel. It's about improving the pliers.

Collapse
 
steveblue profile image
Stephen Belovarich

Very astute observations. I totally agree.

Collapse
 
domas profile image
Domas Juodele

A solid extensive framework backed by solid community might save some pain and time.
Open source libraries developed by devs without big enough community might have some stability issues in edge cases..

Realistically all is about spending time efficiently, getting more/better from same energy. how understandable solution is is important as well.

Collapse
 
thebuzzsaw profile image
Kelly Brown

Excellent post.

It cracks me up that "don't reinvent the wheel" falls flat both in software and in life. Do advocates of this advice not realize that we are inventing wheels in real life all the time? Were we supposed to stop once we had a good wagon wheel? No! We need wheels that can handle F1 racing. We need wheels that work on Mars. We need wheels that can carry 18 tons. We need wheels that have no metal in them. We need wheels that work on ice. We need wheels that cost less. We need wheels for eeeeeeverythiiiiiiing.

And the analogy carries over to software. Take any library that does anything. Does it work in low resource scenarios? Does it favor performance or correctness? Does it favor API simplicity or maximum functionality? Does learning curve matter? Does it work at scale? What is the target audience? What is the upgrade cadence? Is the primary project OK with more dependencies? Does it work with all filesystems? Does it work in all operating systems?

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Okay before I read this. Don't reinvent the wheel. Invent something that doesn't need wheels.

As the lotus founder once said, Add lightness and simplify.

Collapse
 
steveblue profile image
Stephen Belovarich

What a fantastic quote!

Collapse
 
leob profile image
leob

Yes and no.

I don't like it when people pull in a whole node.js package (with all of its own dependencies) when the functionality can be hand written trivially with a few dozen lines of code. I also don't like it when the complete lodash library is pulled in just to have map/filter/reduce and a couple of other utilities which are already available within ES6.

And finally I agree that newer ("evergreen") browsers have come a long way and include a LOT of useful APIs (and much better Javascript engines) which means we often don't need Babel, Webpack, and a host of other 'complicated' stuff. Much more simple, much more lightweight, I'd definitely call that a win-win situation.

But for many projects using React or Vue makes a lot of sense, unless at some point the "native" Web Components spec becomes a viable alternative (it's come a long way but it's probably not quite there yet).

Collapse
 
sally profile image
Sally

I came to dev late, as a grizzly old lady, and the very idea of inserting unknown code into my own code was at odds with years of study and writing, where it's known as 'plagiarism' :D It still blows my mind so many of our favourite apps that dominate the world are built on a foundation of little homegrown random snippets of functionality cooked up by random people in from skyscrapers to classrooms and basements.

I began to appreciate the obvious ones - Formik for clean, readable, easily manageable form validation is a time-saver, for example, and means a team all use the same methods, or date.fns or moment for consistent handling of time. However, relying on them for every little thing still feels lazy. I encountered one in a prior project that worked well enough until we needed to expand its usage, and then it refused to be restyled or reformed, and our attempts to do so were hampered by so many layers and wrappers. Once we wanted to reform it, it would have been faster to write our own. This can be a learning experience for those of us yet to experience the pain of building our own date picker.

Don't reinvent the wheel, but sometimes, the wheel is the wrong shape or it's made of cheese, or even better, it's invisible and you can't see what it's made of at all. Sometimes we need to make nice new wheels that fit!

Collapse
 
mikependon profile image
Mike Pendon (Zym)

I am also an author, but it is an ORM for .NET to intentionally improve-much the existing wheel Dapper. I heard a lot from my network that instead of reinventing it, why not contribute it there?

Do not reinvent the wheel.

Well, I am against to that phrase as also. We must improve (not reinvent) if we think we can deliver the 8 out of 10 features on top of the existing one, and if that would somehow increase much the productivities and the lives of many developers. A friend of mine said, if you are writing additional 2 features to make the 8 a 10, then do not reinvent it (instead contribute it).

My reason to this (like yours) is to solve and improve the wheel, not reinventing it.

I am amazed to all the authors like you who bravely spent time improving the existing wheels, you all have my respects!

Just continue with it, and people will realize the solutions you are bringing.

Let us get off together from our comfort zone.

Collapse
 
moyarich profile image
Moya Richards

Listen no one should have to take a stance on what is best

  1. write your own code
  2. use someone else's code.

You have to choose based on what is best for the project.

I have literally watched a coworker write code for the exact functionality that was already in a plugin, because he believes that his code is always better, he did no research to see what was already created.

Now, here is what I think people should do. Read the darn opensource code. if it has what you need, use it. If it makes more sense to write your own because the original is too bloated, do that. Heck, even go as far as to take the pieces of opensource code that you need.

.... but under no circumstances choose option 1 solely because you "think" your code is always better. Because until your code has been tested, you can't back up that claim

Collapse
 
steveblue profile image
Stephen Belovarich • Edited

Yes, ego needs to be taken out of the equation. I coded a library but do you see me trying to convince others at work to use it? No. It’s irresponsible. It becomes a problem when anyone suggesting something different is branded irresponsible, they are “reinventing the wheel”. It’s a catchphrase at that point, nothing more. I’m not saying this happens everywhere, but it’s a political game that happens at companies.

Collapse
 
codemouse92 profile image
Collapse
 
nreith profile image
Nicholas Reith

Totally cool and fun when you're a student, doing it in your spare time, or have a seriously burning need to improve in a way that requires a total rewrite. But not cool at all when you just go off and do your own thing slowing your entire team down and adding to the pile of technical debt you're creating for them to maintain when you inevitably leave in a year or two. There is a reason many open source projects have billions of downloads. I'd rather bet that they'll still be around and giving me no effort improvements and security/bug fixes with major testing in a few years. Fly by night wheel reinventing in industry is a curse.

Collapse
 
jeastham1993 profile image
James Eastham

I agree with this Steve to a certain extent. A company I used to work for had a client requirement to download emails from a mailbox on a schedule. Rather than using a perfectly good existing tool written and supported by a 3rd party they rolled their own.

Whilst it wasn't a car crash, it was riddled with bugs and never really worked properly.

New company now, same requirement. We use the 3rd party tool. Fully supported, works perfectly, and updates are included. Financially we make a tiny margin on the license, but for the maintainability it's a much bigger win.

Within an application though, I agree completely. Whenever I write domain level code, I keep it as dependency free as possible. Following clean architechure principles, my core codebase is a pure representation of the domain. Dependencies are added at a higher level.

Collapse
 
tomebuljevic profile image
Tomislav Buljević

The phrase has become a bit of a catchphrase, that's true. But when I advise it, it's apppropriate for the tech stack. For example, what if a feature is already implemented, but you just need to poke around a bit to reveal it? What if it's hiding in plain sight masked as something else entirely?

I'm not saying "don't be creative", far from it. I'm just saying, if it's available, use it to its full potential.

And that's all the catchphrase should mean, is it not?

Collapse
 
steveblue profile image
Stephen Belovarich • Edited

Yes, however I have heard the phrase used in other contexts which prompted this post.

Collapse
 
intermundos profile image
intermundos

The issue is very case specific. One time it is faster and cheaper to reinvent, the other time you enter a zone of pain. Very specific buddy, very specific.

Collapse
 
steveblue profile image
Stephen Belovarich • Edited

Good point, buddy. No one is arguing anything different.