DEV Community

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

Posted on

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

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

Most of the time when I hear this argument “don’t reinvent the wheel”, it sounds like it comes from a place of comfort. Engineers are comfortable using the existing tool even when it causes bloat, is badly architected, or could be a cause of poor performance experienced by the end user. The user is who really loses when engineers make decisions in their own best interests.

Maybe the engineer is heavily invested in a framework and doesn’t want to learn something new. The problem could be more systemic. Maybe your company hasn’t moved away from the same stack in several years. These are much harder obstacles to overcome.

When you have to implement a new feature, more often than not there is a solution already built by the open source community. It seems like a no brainer. Use the tool. There are some things you ought to consider before pulling a library off the shelf.

The learning curve

When you adopt open source tools you often don't know what you are getting. The README highlights all the wonderful things you will get.

Installing the package is the first step. You follow the instructions step by step in the README until you run into a problem where the code doesn’t work. You look for documentation. It’s not really there. You google it. Nothing. You dig through the issues on Github. Nada. Finally you decide to look at the source code to scan for issues. The coding style is foreign to you. Stepping through the code you notice it has been optimized.

Never underestimate the time it takes to learn a new tool. Sometimes it takes awhile before you fully understand the impact of using an open source package. You can hit roadblocks you didn’t anticipate.

Customization can be difficult

Even when a npm package does the job extremely well, there are parts of the tool that don't fit with the company's business logic or design patterns. Forking an open source project could be an option, but who want's to maintain that? You might think the feature your team needs could be contributed back to the open source project, but sometimes that contribution could be met with opposition.

A lot of the time engineers use open source tools to implement UI, thinking it fast tracks development in some way. This could mean using a chart library or bootstrap. I have heard engineers say "tough luck if it doesn't conform to the design styleguide, we need to push out a feature this sprint". That's just not cool. As engineers we should be working together with design and UX professionals to implement solutions for the end user. The decision to buy instead of build could come at the cost of collaboration. The tool could speed up delivery, but how will it look in front of leadership when you have to explain you didn't listen to design and UX?

Innovation is stifled

The heavy adoption of open source tools comes at another cost. We are stifling innovation. When nearly everyone is learning the hottest new JavaScript library instead of fundamentals, we lose the skills required to build something from scratch. We lose our connection to the language itself because we are always interacting with an abstraction: the JavaScript framework. The industry is stuck the patterns of the library. We have the entire history of computer science to draw from and opportunities to design new patterns, but all I hear is "redux".

Some of us poke our heads out every once in awhile and say "we can do it different", but do the rest of us hear their message?

Bloat

A more obvious cost of bundling libraries with our applications is the resulting bloat. Several third party libraries cannot be treeshaken. You can't pull in only the parts of the library you want to use. Instead you have to bundle the entire library with your application.

The more dependencies, the larger the bundle, the longer it takes the end user to download the JavaScript. This is particularly important for mobile users that make up roughly 50% of global traffic. It's highly possible a homegrown solution means less code and a lighter bundle.

Conclusion

"Don't reinvent the wheel" is a phrase I've heard countless times over the years. I am told if a library exists, use it. Then I go and implement a custom solution anyways. The result usually means less code, customized for a set the business logic. I write documentation so the learning curve is shallow. The willingness to architect and implement a custom solution maybe one key difference between Senior and Junior engineers or even Principal and Senior engineers.

In the past few years browser APIs have evolved. We have several tools baked into the browser that JavaScript libraries ignore. As evergreen browsers become more prevalent, it's time we start using these APIs more.

Last year when I was coding Readymade, I implemented one-way data binding with a minimal amount of code using ES2015 Proxy. The library overcomes limitations of DOM events by using the BroadcastChannel API for events. A "hello world" to generate a Readymade component is ~1Kb, gzipped. When implementing all the Readymade features, the bundle is slightly larger. This is just one example of how vanilla JavaScript and browser API can reduce the bundle size. Without a custom solution, I would have very few options for custom element development that didn't generate more library code. I wouldn't have been able to define the developer experience and make the API easy to use.

I can hear it now. "Why didn't you use Svelte?"

I'm confident if more people in our industry took the time to learn browser API and JavaScript we could further innovation. Instead of focusing all of your energy mastering libraries, consider how you would implement a library without dependencies. Maybe the result will be something lighter, faster, and delightful to use.

Latest comments (28)

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
 
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
 
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
 
codemouse92 profile image
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
 
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
 
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.

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
 
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
 
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.