DEV Community

loading...
Cover image for Do You Even NPM, Bro??

Do You Even NPM, Bro??

bytebodger profile image Adam Nathaniel Davis ・6 min read

I have a strange confession to make. Until a few weeks ago, I'd never published an NPM package. If that doesn't sound all that strange to you, consider the following:

  1. I've been primarily a frontend developer for the last 6-7 years.

  2. As a JavaScript (React) dev, my life basically revolves around NPM. Every new project I start begins as a "package". Every legacy project I've worked on is a "package".

  3. On some days, I'm less of a "programmer" and more of a "package manager". I install new packages. I uninstall orphaned packages. I upgrade existing packages.

  4. As someone who's been doing dev for decades, the first, middle, and last thing you're ever taught is DRY. And in the world of frontend dev, one of the most obvious ways to not repeat yourself is to bundle your work into packages.

But with all that in mind, I had never actually published my own NPM package. The reason why is a bit convoluted. But if you're in the same boat, I'd like to share a few epiphanies I've had in the last month-or-so.


Alt Text

Packaging Obstacles

I spent the first few decades of my career working mostly on backend code. In fact, for a good portion of my career, there was no such thing as a "frontend dev".

If you're a "backend" kinda person, there are still ways to share / bundle / package code. But in my experience, those paths are fewer and harder to follow.

When I was doing PHP / ColdFusion / Perl, "packaging" your code basically meant copying-and-pasting it into some shared location. When I did C#, we had DLLs - but the vast majority of those were proprietary. When I did Java, it seemed that we pulled in a lot of 3rd-party packages - but there was no great central repository/directory in which we felt compelled to publish our own packages.

In fact, the whole idea of having a public programming profile often left me feeling snarky. Some recruiter would ask if I had a GitHub profile they could look through and I'd think, "Maybe I'll go post all of that proprietary, highly-sensitive, corporate-protected IP that I've been working on. I'm sure no one will mind."

Doing primarily-backend code made public packaging seem highly impractical. The technologies I was using made rampant code-sharing feel awkward. And the nature of the work I was doing made me sometimes fear the idea that I'd publicly post anything at all.


Alt Text

The Sharing Paradigm

Sharing code isn't confined to the world of frontend development. But I believe that the NPM ecosphere makes it far more accepted. When I was doing C# work, if I walked in with a handful of DLLs that I downloaded from the internet, and I now wanted to incorporate them into the organization's app, I'd get a lot of flak over the idea. But when you suggest that your JavaScript project might need a new/different NPM package, there's typically far less scrutiny. In the JS universe, this kinda thing is just considered to be more "normal".

Please note: I'm not claiming that using NPM packages is devoid of its own scrutiny. Depending on what kind of app you're working on, and what kind of company you work for, adding NPM packages (or even updating existing ones) can be a major PITA. But I still think it's easier in, say, your average React shop to consider adding/updating packages, than it is in, say, your average .NET shop.

Still, I haven't started creating NPM packages because I suddenly grew concerned about my karmic footprint in the software world. I got here because it's simply the most practical solution to a handful of key issues. Primarily, I've been in a phase lately where me-and-my-team have been spinning up multiple projects. Every time we spin up another project, I start the process by pulling over all of our "core" functions / Hooks / utilities / whatever. And when I say that I "pull them over", what I'm really saying is that I copy-and-paste them from a previous project into a new one.

I hope I don't have to explain to you the kinds of problems this can create. And yet, it still took me a long while before I finally thought, "Maybe I should put these in an NPM package??" I finally got tired of worrying about the mental baggage that occurs when you have a dozen slightly different versions of a given utility package floating around a dozen different applications. I finally concluded that all of these apps should be sharing the same code.


Alt Text

A Freeing Feeling

Once I finally took the dive and started creating NPM packages, I was kinda surprised by just how much utility code I've been hauling around with me from project-to-project. Obviously, you don't want to create an NPM package out of your app's core functionality - the features that distinguish it from any other app. But once you get outside of the core features, there's just sooooo much code that's... "generic". And IMHO, nearly all of that code is a candidate to be packaged.

Of course, you don't have to do this with NPM. You can directly define a GitHub repo as being a dependency in your package.json, and that's not a bad way to share your code. But I honestly think there are some key benefits to making it a formal package (that I'll discuss in a minute). And your NPM packages needn't be public (although I think there are also benefits to public packages, that I'll discuss in a minute).

The whole process of packaging my utility code has honestly felt rather... freeing. To me, one of the most powerful allures of coding is that we can, in theory, solve a problem once - and then never have to solve that problem again. And yet, when faced with the constraints of dealing with corporate codebases, I frequently found myself "solving" the same problem over, and over, and over again.

But converting stuff into packages feels like more of a "true" DRY solution. I write the code. I publish the package. I consume the package from multiple projects. And, if necessary, I fix/expand the project from one single repository.


Alt Text

Packaging Can Make Your Code More Rigorous

I've noticed a positive side effect of creating NPM packages: I'm more rigorous about writing - and checking - my utilities. Allow me to explain:

Maybe I have some simple function that just generates a random ID. I've used that functions hundreds of times - across dozens of codebases. So do I create unit tests every time I copy that function into a new codebase? Nawwww. Probably not.

But if I'm going to convert that function into an NPM package - a public package - I feel a greater compunction to add the appropriate test coverage. And when I do that, you know what?? Sometimes, I realize that there were a few edge-case flaws in my function. They probably never came up in the apps where I used the function - but they were flaws nonetheless.


Alt Text

Building A Legacy

The last "benefit" of NPM packages could be completely in my head. But it's kinda nice to think that, over time, I'll have this ever growing "legacy" of public software. It doesn't matter if most of that "software" consists of super-simplistic utility functions. It's just nice to think that, at some point, I'll be able to say, "Well... here are the 100 NPM packages that I maintain."

Granted, this isn't the only way to have a "legacy". Just having a GitHub account with a few public repos will also serve this purpose. Nevertheless, it's kinda cool to see when people are downloading your NPM packages - something that I've noticed happens far less frequently when the code is just contained in a public GitHub repo.


Alt Text

Conclusion

Obviously, publishing a few NPM packages doesn't magically make you a better dev. But... it certainly doesn't hurt. And now that I've finally waded into the process, I really think it's something that every "frontend dev" should try - or at least, become acquainted with.

Discussion (8)

pic
Editor guide
Collapse
sebring profile image
J. G. Sebring

I can totally relate. What bothers me is that all these utility functions are made during company hours. Can you really publish them on your private github, or even take the decision "These stuff will go under the MIT-licence"?

Collapse
bytebodger profile image
Adam Nathaniel Davis Author • Edited

These are good points - and they're pretty much the same points that kept me from taking an NPM-package-approach for years. I don't claim to have perfect answers, but these are some of my opinions on it at the time being:

For the sake of argument, let's say that you have some ridiculously-simple function. For me, a good example would be this: npmjs.com/package/@toolz/create-ra...

There are a thousand different ways that you could choose to generate a random ID. But I got tired of constantly rewriting/copying the same logic every time I needed to do this. So I put it into an NPM package.

I can't honestly remember the first time that I wrote this function. Was it for an employer? Maybe. I'm just not sure. But I know that in the last several years, I've used it at numerous jobs - and in numerous private projects. So it'd be quite a stretch to claim that it's the "property" of any one employer. More importantly, the logic within it is just really... generic. It's not generating random IDs according to a given company's standard. Nor does it contain the kinda logic that, say, saves those IDs in a company database or retrieves those IDs from a company endpoint. It's just a dead-simple utility function.

What if you wrote a standalone function that divides by 2? (OK... that'd be kinda silly - but I'm just illustrating a point.) If your employer paid you to write that code, it would technically be "their" code. But, c'mon... it's a divide-by-2 function! If your employer pays you to play a drum, that doesn't mean that your employer now owns the act of hitting a drum with a drumstick. Nor would they own the sound that's generated from hitting a single drum one time with a drumstick. They would only own the compositions they paid you to create (just as they own the apps that we develop in our jobs).

Also, you aren't required to use the MIT license for NPM packages. In fact, you can kinda have whatever license you want. The MIT license is just sorta the "default" that you see on NPM. And of course, you don't have to publish public packages on NPM. You can have private packages - although that diminishes many of the benefits that I'm talking about here.

So in summary, I'm not encouraging anyone to start pushing their company's IP out to NPM - and then claiming it as their own. But if you've written something that's truly a utility function - the kinda functionality that you're gonna find yourself copying-and-pasting between different work projects, and personal projects, and even between multiple employers - then yeah, go ahead and put that code into a package.

Collapse
stereoplegic profile image
Mike Bybee

Great org name. Surprised that was available.

Thread Thread
bytebodger profile image
Adam Nathaniel Davis Author

yeah - I had to cycle through quite a few already-taken "orgs" before I found that one!

Collapse
ibrahimshamma99 profile image
Ibrahim Abushammah

You are right, I guess we need a policy to manage Open Source work in Companies' hours.

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

That's a great point that I didn't even touch on in this post - but I know that there are some companies that encourage and quantify the open source contributions made by their employees. I think those companies are the exception. But they do exist. And if you had that kinda policy in place, it would encourage more of your own coders to avoid copying-and-pasting "utility" code from one project to another.

Collapse
kgilpin profile image
Kevin Gilpin

Usually when I go to the actual repo of an NPM package it turns out to be just one or two functions. So I copy and modify it to be exactly what I need. NPM can be more like a bunch of Gists than actual libraries sometimes :-) When I add a dependency, I want to do something sophisticated.

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

Oh, I totally feel that. And this whole little "journey" for me actually started with... Gists. Before I ever created a public repo, I started making little Gists for myself. Then I eventually started creating a few repos. And I only just recently started making some of that stuff into NPM packages.

While I can't disagree with this sentiment in any way, the whole reason I started going to NPM packages was because Gists end up spawning continual cycles of cut-n-paste. And if that Gist is ever updated, you don't see those updates where you've copied-n-pasted it to. Of course, if the package is dead simple, then there may be no future reason to update it. But I got tired of starting every new project by copying-n-pasting the bits that I needed in my new project over from my most recent project.