NPM & left-pad: Have We Forgotten How To Program?

Okay developers, time to have a serious talk. As you are probably already aware, this week React, Babel, and a bunch of other high-profile packages on NPM broke. The reason they broke is rather astounding.

A simple NPM package called left-pad that was a dependency of React, Babel, and other packages. One that, at the time of writing this, has 11 stars on GitHub. The entire package is 11 simple lines that implement a basic left-pad string function. In case those links ever die, here is the entire code of left-pad:

module.exports = leftpad;
function leftpad (str, len, ch) {
  str = String(str);
  var i = -1;
  if (!ch && ch !== 0) ch = ' ';
  len = len - str.length;
  while (++i < len) {
    str = ch + str;
  }
  return str;
}

What concerns me here is that so many packages took on a dependency for a simple left padding string function, rather than taking 2 minutes to write such a basic function themselves.

As a result of learning about the left-pad disaster, I started investigating the NPM ecosystem. Here are some things that I observed:

  • There’s a package called isArray that has 880,000 downloads a day, and 18 million downloads in February of 2016. It has 72 dependent NPM packages. Here’s its entire 1 line of code:
    return toString.call(arr) == '[object Array]';
  • There’s a package called is-positive-integer (GitHub) that is 4 lines long and as of yesterday required 3 dependencies to use. The author has since refactored it to require 0 dependencies, but I have to wonder why it wasn’t that way in the first place.
  • A fresh install of the Babel package includes 41,000 files
  • A blank jspm/npm-based app template now starts with 28,000+ files

All of this leads me to wonder…

Have We Forgotten How To Program?

On what possible plane of existence is this a better solution to past problems? How are hundreds of dependencies and 28,000 files for a blank project template anything but overly complicated and insane?

I get the impression that the NPM ecosystem participants have created a fetish for micro-packages. Rather than write any functions or code, it seems that they prefer to depend on something that someone else has written. It feels to me as if the entire job of an NPM-participating developer is writing the smallest amount of code possible to string existing library calls together in order to create something new that functions uniquely for their personal or business need.

Functions Are Not Packages

Functions are too small to make into a package and dependency. Pure functions don’t have cohesion; they are random snippets of code and nothing more. Who really wants a “cosine” dependency? We’d all really like a “trigonometry” dependency instead which encompasses many “tricky” functions that we don’t want to have to write ourselves. This is much more akin to how .NET and other frameworks create a “core” library of basic functionality. Such a library is vetted by the creators of the language and pretty much guaranteed to be correct and bug-free.

Third Party Problems

There’s absolutely no guarantee that what someone else has written is correct, or even works well. Even if correct, is it the most optimal solution possible? At least when you write the code yourself, you can easily modify it to fix bugs and improve its efficiency. Not that there should be many bugs in 1 line functions.

Second, even if the package’s logic is correct, I can’t help but be amazed by the fact that developers are taking on dependencies for single line functions that they should be able to write with their eyes closed. In my opinion, if you cannot write a left-pad, is-positive-integer, or isArray function in 5 minutes flat (including the time you spend Googling), then you don’t actually know how to code. Hell, any of these would make a great code screening interview question to determine whether or not a candidate can code.

Finally, stringing APIs together and calling it programming doesn’t make it programming. It’s some crazy form of dependency hacking that involves the cloud, over-engineering things, and complexity far beyond what’s actually needed.

What’s worse is that if any of your code (or the 3rd party library code) has a bug or breaks, you won’t know how to debug or fix it if you don’t know how to program.

Strive For Few Dependencies

Every package that you use adds yet another dependency to your project. Dependencies, by their very name, are things you need in order for your code to function. The more dependencies you take on, the more points of failure you have. Not to mention the more chance for error: have you vetted any of the programmers who have written these functions that you depend on daily?

Take on a dependency for any complex functionality that would take a lot of time, money, and/or debugging to write yourself. Things like a database access layer (ORM) or caching client should be dependencies because they’re complicated and the risk of the dependency is well worth the savings and efficiency.

But, for the love of all that is programming, write your own bloody basic programming functions. Taking on dependencies for these one-liners is just nuts. Don’t believe me? Just ask the React team how well their week has been going, and whether they wish they had written those 11 lines for left-padding a string themselves.

Follow David Haney on Twitter at @haneycodes

301 thoughts on “NPM & left-pad: Have We Forgotten How To Program?

    1. ungoldman

      Yeah, I think you’re just fundamentally misunderstanding the npm ecosystem and small module philosophy. +1 on the above link from Luis. The real problem yesterday’s events exposed is a design flaw in npm. Immutability at the centralized authority level and more decentralization of package distribution is the solution, not “write more functions yourself.”

      Reply
      1. Jared

        Actually, after reading the link from Luis, I draw the same conclusion as David. Where is the complexity? Just write it yourself.

        Seen the same breakage situation happen all over the npm ecosystem with regards to another package called rimraf. I guess it is just too hard for most to remove a file, or tree of files, from the file-system using the plain old node API. Just write the function yourself.

        If you must, make it your own npm package, and depend on it. Strive for few external dependencies.

        Reply
        1. Jakob

          Rimraf is hugely beneficial. NPM version 2 caused a crazy deep hierarchy for all the node modules. To
          Too deep a path on Windows makes it so you cannot actually remove the files. Rimraf renames the directories, including children, and deletes them.

          Reply
        2. Slava Vishnyakov

          The complexity is in the all of the off-by-one bugs and forgotten cases. The same can be said about fro ex. HTTP client. What’s the big deal, it’s just “GET / HTTP/1.0\r\n\r\n” – then you understand you need headers, then encodings, then non-conforming servers, then uploads, etc..

          In left pad you see things like var i = -1 which probably started life as var i =0 and a off-by-one bug.

          return toString.call(arr) == ‘[object Array]’;

          You probably need to console.log it first. Also as soon as you log it – you start to think – is it a correct way? Etc.. It’s just not worth the programmers time to debug all those minor things. That’s why libraries exist, that’s why standard libraries exists – so that millions of programmer don’t waste their time writing (and debugging!) the same stupid thing.

          Reply
          1. Wombat

            Lines of code is not a good metric. If you make a really efficient random number generator function it might make sense to package it as a module even though it might only be a few lines of code. That said, there is a difference between an HTTP client and isArray. HTTP is genuinely complex and if all you need is to grab a resource from a URL you really don’t need to know the intricacies of HTTP protocol. The scope of an HTTP client library is well defined and actually hides complexity that most developers will never need to access. isArray is a different case. It is not actually hiding any complexity. If you are going to develop things in javascript you need to know how to deal with arrays as well as other default object types. If you don’t know, you need to find out. Otherwise it will eventually bite you in the ass. In this instance, isArray actually depends on string representation of an array object to stay the same. And I don’t think [object Array] string is part of any standard, so the next implementation of JS might do things differently. The library is not hiding complexity, it is hiding important implementation details.

          2. Ivan

            This. When our devs pull low level modules (nothing that is 1 line!), its not because they cannot code, but because their head space is focused on making our actual project something amazing. I don’t want my devs spending time recreating something that has been solved.

            Totally agree that there are some ridiculous packages out there, but I think there is a legit use case to pull small libraries and low level tools, its part of the foundation of the progress of programming to be able to abstract up from whats already been solved to spend your time solving larger problems.

          3. xtifr

            > “The complexity is in the all of the off-by-one bugs and forgotten cases.”

            So, in other words, your answer is “yes, we have forgotten how to program”. Because anyone who can actually program could write that function in their sleep without any chance of off-by-one bugs.

          4. Nicholas Bailey

            Honestly, if you write a left-pad function and don’t write a unit test to catch off-by-one-errors, you don’t deserve to be a professional developer.

        3. Ryan O’Har

          > I guess it is just too hard for most to remove a file, or tree of files, from the file-system using the plain old node API.

          It’s not trivial.

          > Just write the function yourself.

          > If you must, make it your own npm package, and depend on it. Strive for few external dependencies.

          Why? Someone already wrote it. Bundle the dependency if you like.

          Reply
        4. Dorin

          Following this philosophy, then STD library should be a 100+ small libraries for every string function.
          these are anemic NPM modules that should be disregarded. instead should be bundled into a bigger module, the one that tackles Array problems, another for String manipulation.
          a well defined boundaries for a module should be taken into consideration. as per Luis link. A CPU incorporates a lot of functions, but it’s boundaries are well defined . otherwise we would have to have few hundreds CPU in each PC.

          The basics of programming have been forgotten.

          Reply
          1. Jason Karns

            What difference is there in pulling in a StringUtil bundle of 50 functions when I only need one? There is no increase in quality, reliability or maintenance by grouping a bunch of utility functions into a larger lib.

          2. Wombat

            Jason, of course there is a difference. The difference is between a single library with 50 maintainers and 50 libraries with single maintainer each.

        5. Dann

          By the same illogical conclusion, programmers should download all the packages and redistribute them with their project to ensure they are always there and as expected. This was the whole point of a package manager.

          Reply
          1. Allen


            By the same illogical conclusion, programmers should download all the packages and redistribute them with their project to ensure they are always there and as expected. This was the whole point of a package manager.
            ” ~Dann

            There’s nothing logical about creating a fragility. I’m a bit shocked that the node.js world seems to not understand the importance of anti-fragile. It’s 2016. If you want to live in the enterprise you can’t have massive failures let alone due to petty stuff like this.

        6. bid

          Yeah! Just write your own function for deleting files!
          That supports recursive deletion of infinitely complex trees.
          And globbing patterns.
          And intelligent error handling.
          And automatic retries after configurable timeouts.
          And special error handling for Windows systems.
          And is usable as a library and stand-alone.

          It’s not that hard – it took 17 contributors only 5 years, after all. 😉

          Reply
      2. stu

        You can’t have immutability at the centralized authority without copyright assignment to the central authority.

        Reply
        1. drbeagle

          Of course you can. It’s open source. Once you give it to me, there should be no expectation that you can take it back.

          Reply
      3. james

        ” misunderstanding the npm ecosystem and small module philosophy”

        I think the philosophy is invalid. And you know what? NPM itself is the proof.

        The most popular and useful packages on NPM are not ‘little blocks that do 1 thing and 1 thing well’. They are proper modules. They do a bunch of highly related things, and they do it well.

        The best Node modules are those that ‘could have been written’ by a small team of solid Engineers working for ABC corp. But they just happen to be giving it away.

        Reply
    2. Jim

      Prior to the emergence of jQuery, JavaScript development was mess. Polyfills for different browsers and other abominations all copy-pasted from project to project. It was a toy language that could be hacked into doing cool things (Google Maps and Gmail). The idea that a layer of abstraction that could hide browser complexity was a revelation. This idea took hold and grew till we got to the sitation where we are now. Simultaneously the “one language to rule them all” cargo cult and SPA trends emerged and JS ended up being in the right place, at the right time with the right toolsets.

      Any edge cases and incompatible language implementations -including incorrect or missing operators(!) can be abstracted away and incorporated into the package and shared. I personally think that modules are a good way of working around the rickety mess that is JavaScript development. Perhaps the real answer it to stop fetishising a 20-year-old language that was thrown together in a week, and make a concerted effort to standardize on something better.

      Reply
      1. Evan Dorn

        “Perhaps the real answer it to stop fetishising a 20-year-old language that was thrown together in a week, and make a concerted effort to standardize on something better.”

        Got it in one.

        Reply
    3. Chris

      There’s a cognitive dissonance going on in this community that I just can’t wrap my head around. I get the impression that all this “hiding complexity” is side talk for “someone else on my team’s problem”. This doesn’t even pass the simplest logical sniff test test, people. I like Sindre. He makes cool stuff, but man…

      “Imagine if PC manufacturers all made their own CPUs. Most would do it badly. The computer would be more expensive and we would have slower innovation. Instead most use Intel, ARM, etc.”

      What in holy hell is he talking about? This is such a broken analogy. A CPU is a self-contained unit that can be plugged in all sorts of systems and has value on its own — but it’s made up of many different functions that a single team has worked on and developed and tested and is totally vested in delivering the best CPU to market.

      A better analogy would be to compare some engineering team designing a CPU and deciding to break it apart into 10,000 micro components and handing them all off to PC manufacturers.

      “You wanted to buy a CPU from us? That’s not how we do business. We found it was much quicker to push out features to you if we went for a more lego block approach. Instead of a CPU you *get* to choose a combination of any of our 1,000 micro components. Each one is on a different release cycle to ensure velocity and it’s up to you to ensure the versions you are using are compatible. Oh. We also found is was better to outsource our 1,000 components to 100 different short-term contractors across the world. The contract terms? Yeah. We let our contractors terminate the relationship at any time and we don’t ensure any sort of QA. They’re all great teams, don’t worry about it! Also, none of these teams are expected to know what the other teams are working on or what changes they are developing. We feel that organizing at that level slows down innovation. Almost forgot! You also get to solder everything together yourself and how you see fit — we supply you the soldering board and the solder at no additional charge!”

      Does this seem like a sane world and a company you’d want to do business with? Maybe. I sure as shit wouldn’t. Is this a symptom of open source? Maybe. But there are tons of projects and ecosystems out there that are open source and don’t operate this way and don’t get the kind of slack this community gets.

      Reply
      1. KI

        Indeed true.

        Especially npm world seems to be rampant with dependency hell to trivialities. That said I have noticed ridiculous “single line” gems also in rails worlds (with supporting cohorts raving that one must use such gem instead of wasting time….). Well, from my long time experience I have learned that it’s les expensive and actually more maintainable to add depencies for trivialities, since often those trivialities end up being extra package since needs of the project are slightly different. Especially when some single liner has awkward performance bogging whole system down. For example, that leftpad, sounds sad (for js) if that’s most reasonable way of doing padding in js.

        Reply
      2. seb

        Chris,
        Word! You’re so right. It is insane to rely on a packet which simply does ‘return x==y’.
        Your LEGO-CPU analogy made my day 🙂

        Reply
      3. Joey

        ^^^ THIS. Reading that response only validated for me exactly why Node package ecosystem is broken. He mentioned that small code snippets are worth importing, but I’d rather not import a package that includes finding a Windows user’s home directory if I only ever need to run on Linux. It’s that kind of thoughtless, careless programming that leads to bloat and unnecessary complexity.

        Look at the way “node_modules” becomes a relative dependency of each dependency. Stating it that way in plain English makes it clear that this is a potential recursion problem. Specifically, a filesystem recursion problem. Go ahead and Google for “npm windows character limit”. It’s the inevitable outcome of such a design. Or look at the following post:

        http://www.jagregory.com/writings/docker-container-out-of-space/

        That’s what happens when you hit the inode limit on Linux filesystems. And you’ll notice that the only place this ever happens is in the npm ecosystem. Directory limits, open file descriptor limits, pathname limits… all npm.

        The idea that your project might feasibly encounter an OS or filesystem limit by simply installing its own dependencies is absurd. I agree wholeheartedly with the OP; programming today (at least in JS world) involves almost as much work choosing what 3rd parties to depend on as it does writing and thinking about your own code. Being lazy used to be a great quality in a programmer — it typically translated into being extra efficient and ensuring that you wouldn’t be replicating your efforts on the same logic over and over again. Now, it seems to have produced a generation of programmers who believe it’s easier to import someone else’s snippet, no matter how bloated and how many unnecessary genericisms have been introduced in order to make it publicly consumable, than to think thoroughly about your own code and treat complexity as the enemy that it is.

        Looking at that left-pad module makes me cringe.

        Reply
        1. ryan

          Exactly, the JS community has moved from copying and pasting snippets from a web page to importing them using npm packages

          Reply
    4. mirfilip

      I gave myself couple of days since this blogpost was written to digest the community reaction and the comments here. It’s been around two years since I stopped coding in JS myself but I still follow the ecosystem. I think this gives me a good position to comment on.

      David’s examples and conclusions may be a bit overdrawn but they indeed show there are some fundamentally wrong things with JS ecosystem nowadays.

      Granted, people defending “make a dependency of everything” approach had some valid points too. Here are my thoughts:
      * Literally no-one in their sane mind would copy&paste the solutions to every problem just because they wrote it themselves. If you do, you’re a programmer waiting to be proven wrong. Making your solution public, scrutinizing, testing against “yet another” edge case no one thought about before is a great approach. This statement is language agnostic, really. If you stick to your holy solution, promote that to become a part of your “standard library” and have it peer reviewed. All these people that commented for copying – they also forgot how to program, cause DRY principle is known and widely accepted for some 20 years or more.
      * Yes, it could happen to bigger packages. Removal of left-pad is NOT to be blamed. But still… Take the opportunity to think about the problems NPM has. And no, “it has 50k downloads, it has to be awesome” is not an argument. If any of the bigger packages depended upon this left-pad, with all the problems it has (just pointed out by blogpost comments alone), it’s really weak. You’ve got to wonder what the criteria of validating the dependencies are for maintainers of these frameworks. You think such mistakes happen to JS only? No. I can name examples from Ruby, Python, Java and PHP. The difference is the mentioned languages had their “big packages” stick around for long enough to have been vetted and improved. You don’t have time for that because of constant churn… which segways me to another point.
      * I once read https://jsinsights.com/why-javascript-churn-is-a-good-thing-607b0d53018c which left me totally dumbfounded. How do you guys cope with the situation that the technology/state of the art approach/framework that you started your project with, is becoming “not cool anymore” by the time you finish it? No, “life fast, die young” doesn’t apply here. It’s fine for homemade projects. It’s not for “close-to-enterprise” level solutions. The just released big project written in AngularJS 1.x is not cool anymore because everyone does it React way.
      * Everyone agreed the modules like “isArray” or “isPositiveInteger” are bad and should be a part of some kind of “standard library” of the ECMA. I remember the sad times before jQuery and the fresh breeze it brought. That was because everyone was sick and tired of handling all the quirks themselves and this tool solved things. Don’t forget, JS was still a frontend, browser based scripting language. You could argue, sticking with a bad language “patched” by such a good utility library was the best thing community had. The problem is, since then, JavaScript started to become a backend language (NodeJS) with almost no improvements to the “stdlib” (yes, I’m aware of ES6). Don’t get me wrong, I’m the last person to push NodeJS out of the backend party, but doesn’t it give you red alerts when you start your next project based on that? A language suited for one thing is not necessarily a good candidate for another. Remember Java and applets?

      So, having expressed my doubts on the _current_ state of things, I cheer JS community to grow out of child age problems and move on.

      Reply
    5. Shadowfury

      That doesn’t sound like hiding complexity to me. It’s more like convenience and even laziness.
      -1

      Reply
  1. Noah Yetter

    I think you’re pointing to the right symptom and drawing the wrong conclusion.

    These packages proliferate because JavaScript’s standard library is so woefully inadequate. It’s ridiculous that anyone has to write their own left-pad function in the first place. The problem isn’t that people “don’t know how to code”, it’s that they’re operating in an environment where basic functionality has to be implemented by end-users (i.e. developers), and where it’s — perhaps reasonably — standard operating procedure to import someone else’s solution rather than write your own.

    And it’s not just JS, there are plenty of examples in other ecosystems. In Java there’s no reason to write your own StringUtils.isNullOrEmpty() when you can just import Apache Commons or Google Guava. That said, it’s embarrassing that such a commonly-needed thing isn’t in the JDK itself.

    Reply
    1. A

      Actually he’s drawing the right conclusion — and you just proved him right. You don’t know how to program.

      Reply
        1. Shadowfury

          Except that in this case it’s much easier and faster to just reinvent the wheel instead of using an already invented one. But only if you have basic programming knowledge, which is the issue here.

          Reply
    2. Rando

      This^
      I struggle to put into words a satisfying exasperation, capturing my dissatisfaction with the javascript language and emphasizing how the community’s efforts to tie up all the loose ends with wrappers is all they can do to make the javascript usable-enough to be excited about it. I mean seriously, this is a language where every single declaration and keyword needs a handful of boilerplate, workaround, and hack-lasagna to convince the run-time to do exactly, and only exactly, that single operation you need done.

      Reply
      1. Beeen

        what? I don’t know what javascript you’re using, but the one I use is amazing and does exactly what I tell it to.

        maybe it’s because I know how to program…

        Reply
        1. Vince

          I agree with this fellow. He probably does know how to program. But I don’t, and I use npm. I’m probably 19 and leaking credentials on Github. Or maybe I’m 45 and Node is interesting to me after a career in ________. Or maybe I’m 32 and I work in QA. You just never know. The level of skills required for different requirements within different size teams is so varied. Supposedly JavaScript was supposed to be somewhat accessible, and we aren’t shoving the entirety of ‘programming’ down the development pipe… which is one reason some people distinguish between ‘programming’ and ‘coding.’ It also may be why some people are and some people are ‘junior developers.’ I’d say creativity is a sign that mastery is emerging.

          Reply
    3. foobar

      > In Java there’s no reason to write your own StringUtils.isNullOrEmpty() when you can just import Apache Commons or Google Guava.

      So it has come to this?

      Reply
      1. Rob Janson

        Unfortunately, we have an entire generation of programmers who don’t know how to program. They are a symptom of our successes, modular programming and assembly of components has led to importing if statements. That they aren’t aware of their lack of knowledge is not the issue – that we created them is.

        Reply
        1. Chuck W.

          They may or may not be able to code, but they sure can stitch together hundreds of disparate “modules” to build a more or less functional, if not provably so, system. It’s about saving time by not having to remember the language’s idiosyncrasies or belting out a few lines of code for a function or maintaining a local repository if something critical to your project disappears.

          Do the developers who live in this echosystem (deliberate spelling), unit test any of these functions to ensure they an handle all edge cases, or at least all the edge cases that might occur in their project? I’ve seen too many questionable code snippets in the comments and blog posts by others in responding to this hot mess to have any faith this is being done.

          Reply
    4. Tom Dong

      Totally agree.

      If you grab a CS professor who definitely knows how to program but isn’t an expert in JS, and ask her to write isArray, she would either just write instanceof Array, introducing a bug without noticing, or she would have no idea and search everywhere on the internet, find multiple solutions, and read through all the comments trying to decide which one looks most reliable.

      Or, she can just look at the module with 18 million downloads, which means it has to be good, and either copy its code or just add it as a dependency.

      Reply
    5. RandomStranger

      Your comparison is utterly ludicrous. Apache Commons is a full-flexed library, with lots of useful functions in a single package. It’s pretty much exactly the *opposite* of having to include “Apache CheckStringForNullOrEmpty” to add a single useful function to your project, and then having to include “Apache LeftPadString” to get another, and each of them pulling in a dozen more dependencies for code that you could just write yourself in just a handful of lines. And the fact that you can’t see the problem with that is what proves the original point of the article.

      Reply
    6. Rolf

      > In Java there’s no reason to write your own StringUtils.isNullOrEmpty() when you can just import Apache Commons or Google Guava.
      But why the fuck do I need to import some huge package for a simple ((string == NULL) || (string.length() == 0)) ? Stuff like JDBC, yes. But that? Seriously?

      Reply
      1. Sammy

        This is actually a perfect example of the problem at hand. Look at your code again.

        If the string is NULL you’re going to get an NPE when your code tries to run string.length()

        The correct method would be:

        if (string != null && string.length() == 0)

        But otherwise you’re right. You don’t import a massive package for a single use, that’s silly. You import it to provide a series of useful quick functions to improve legibility. If it’s a one time thing? Just copy someone’s solution from online, don’t import and entire package.

        Reply
        1. Thomas

          Your just wrote String.IsEmpty not IsNullOrEmpty.. seems the author meant programmers like yourself. And just to make the burn complete the NPE will not occure since, (s == NULL || s.length() == 0) will already return true, if (s == NULL). That’s short circuiting .. most languages do that.

          Reply
          1. Nerot

            If the string is null, the string.length() will never run, as you only need one condition to be true in an || statement for the language to just jump right into the code block.

            whereas in your code, if the string is null the language will skip the following code block altogether, which is not the desired behavior of an isNullOrEmpty function.

        2. matt

          actually if the (string == NULL) part evaluates to true, the second half of the expression won’t be evaluated. it’s called short circuiting. I guess kids today really don’t know how to program 🙂

          Reply
      2. PhiLho

        You won’t import the library for this specific function! But for all the useful functions it has. And since it has also this function, why not use it?
        BTW, that’s null, not NULL: it shows that repeatedly writing “simple” code might still lead to typos and errors (more subtle: | instead of ||).
        And in Java 8, having such function at hand is useful as it can be used out of the box as predicate in other functions (like filter, etc.).

        Reply
    7. JN

      I completely agree with you.

      Sure the StringUtils example is unfortunate, but overall the problem is JS and NPM ecosystem, not that devs can’t program.

      JDK has String#isEmpty() method. How is calling this method different than adding dependency on micropackage in NPM? Sure you have to include dependency, but that’s only because there is no other way (sans writing it self) how to get the functionality. It’s still third party code and IMO it’s irrelevant who the third party is.

      Reply
    8. Suresh

      I wont import Apache Commons or Google Guava just for StringUtils.isNullOrEmpty. Aren’t Underscore, Lodash, Jquery just doing the same as the Java libraries for Javascript? I still don’t like why someone wrote Lodash as better underscore, kind of violating the DRY principle.

      Reply
    9. Jonathan Cast

      This. A thousand times this. A language that’s missing either of those two functions from its standard library *is not mature*. The solution is to ditch JS and switch to a mature language.

      And, for the record, if the OP thinks the majority of working (and productive!) programmers have *ever* been “able to program” in the sense used in this article, I have many historic bridges for sail at steep discounts.

      Reply
  2. Dwayne Charrington

    Spot on, David.

    This is the one thing that really concerns me about front-end development as a whole. We have become so dependent on tooling and package managers, we don’t realise how weak the foundations of the ecosystem actually are. The entire front-end development ecosystem is one massive house of cards, pull out one of the cards and it all falls apart.

    I am honestly surprised that something like this did not happen sooner to be honest. If developers can’t write their own left padding implementations, maybe the end of mankind is going to happen sooner rather than later. You point out there are packages for isArray and other numerous basic tasks that require very little code to implement. We’ve gone package mad. There are thousands of packages with just a few lines of code, who is using them nobody knows.

    The flaw with Npm is that it encourages this micro package approach so much, you look at packages like Babel and it does your head in tracing all of the dependencies. One dependency sometimes has upwards of 30 or 40 dependencies, but guess what, most likely each of those dependencies has their own dependencies as well. It can really get quite perplexing, once you go down the rabbit hole you never truly reach the bottom when it comes to Npm packages. One package can possibly have hundreds of dependencies, no wonder Npm is slow.

    There is a meme here.

    “Yo dawg, I heard you like Npm packages, so we put an Npm package in your Npm package, so you can install while you install.”

    Reply
  3. Rick Suggs

    You make a good point but it’s a bit exagerrated and I’ll informed. left-pad was not a direct dependency of React, or Babel. left-pad has a handful of dependents, but one in particular, line-numbers, which offers more than a one-liner of functionality, was a dependency of several high profile projects.

    Reply
    1. Justin

      But this itself is an illustration of the problem with the micro-dependency philosophy that’s best summed up by the phrase “house of cards”: all the damage done by the kik/unpublishing issue is due to the hidden dependencies inherent in the npm ecosystem. Major projects were taken down without ever choosing that dependency or even being aware of it. AAA projects are built on opaque foundations. If the leading JS libs today don’t even have a grasp of their dependencies, how is any less-rigourous, less-engineered project supposed to confidence in its stability or quality?

      Reply
      1. hugo

        Stability and quality are ensured with unit tests, and all this projects have them.
        But people are confusing modularity with an npm flaw ( the ability to change history of something published). Without that flaw, this approach has lots of advantages.

        Reply
  4. Aleksandar Chalakov

    One advantage of micro packages is that if a certain piece of code is used in different packages, there is only one implementation of it sent to the client, instead every module re-implementing the same function thus increasing the client code footprint. That said, the price we pay for this is high. What if a hacker takes control of the NPM account responsible for one of these one liners? The possibilities are endless.
    Hopefully this un-publishing incident will serve as a wake up call.

    Reply
    1. Dylan McCall

      > only one implementation of it sent to the client, instead every
      > module re-implementing the same function thus increasing
      > the client code footprint.

      Ha. Ha. Ha.

      That just isn’t how the NPM community thinks. Everyone sharing one implementation? How are you supposed to “innovate” like that?

      https://www.npmjs.com/package/node-string-pad
      https://www.npmjs.com/package/pad
      https://www.npmjs.com/package/pad-left
      https://www.npmjs.com/package/left-pad

      There are probably more. Incidentally, pad-left is more efficient than left-pad for a completely obvious reason, but I suppose it happens left-pad is a nicer name. I’m sure there are several other implementations with names like spud and woodchip.

      Reply
      1. Thomas

        pad-left is no more efficient than String.repeat (ECMA6) + String concatenation at actually producing a padded string (it’s actually quite a bit slower). What it does is depend on a library (repeat-string, from the same author) that shamelessly cheats at benchmarks by caching the last result and input string in the parent namespace. The benchmarks are then ran using the same input, meaning it always pulls from the cached result and never has to modify it. The result being that it appears to be very fast when you run benchmarks, but if you ever use a different pad character, it will clear the cache, meaning it actually has to do the work of generating the string again. If you’re generating line numbers, then this can actually be somewhat useful, but if you have String.repeat already (which you do), then just use it. It’s a one liner. A one liner that could have avoided this mess. Even if you don’t have String.repeat, replacing it without cheating and getting near String.repeat speeds is trivial.

        Reply
    2. Michal Jarosz

      Not so sure about the `only one implementation of it sent to the client` part.

      With npm2 I’m pretty sure I would get a separate copy of left-pad.js for every dependency in the project that has a dependency on left-pad.

      But we’re all in npm3 stage now, right?

      Right. The thing is: I still am not aware of what dependencies my dependencies have. I wasn’t aware I used left-pad every day in my work. I might have even written my own left padding function or, even worse, add another dependency to another module with same functionality. Then I’d have two pieces of code, doing the same, but implemented in two different ways, and both send to client.

      Reply
    3. rasenplanscher

      Have you actually looked in a `node_modules` directory? The way it works, you get the same piece of code many times (possibly different versions of it) – there is no lesser code footprint. If anything, it increases. The benefit lies in not re-inventing the wheel, while the price is actually *more* code.

      Reply
    4. Alex-PK

      This is not entirely true with npm.

      Each package you depend on could depend on a different version of another package, and npm will happily download it multiple times, and when you package it for the client, it will be repeated n times in the bundle.

      If npm did proper dependency graph check, js developer would be forced to respect semver, for example, and to maintain their packages or risk conflicting with others and lose karma.

      This would improve the package ecosystem a lot, IMO.

      Reply
  5. Ian

    In a lot of Javascript environments, space is at a premium. Downloading that 150kb trigonometry library has just worsened your page response time. Several larger libraries like Underscore (and Lodash) have actually intentionally split themselves into sub-modules because people usually only ever load them to use a single merge function.

    Rewriting these sorts of things is totally possible, but each time you do you’re violating the DRY principle. The issue here isn’t how large or small a dependency is, it’s how to cope with churn in your dependency tree. A large module could just as easily been removed from NPM and the same problem would have occurred. There are solutions that exist to freeze, localize and otherwise harden dependency modules, but none are considered standard yet. This, most likely, will bring them to the forefront.

    Reply
    1. mow

      Isn’t there something in the toolchain to trim and re-package the included stuff down to stuff that’s actually used during deployment?

      Also, including 150kb is still better than including 20x 0.5kb. http overhead can be ridiculous nowadays.

      Reply
      1. Samuel García Martínez

        I don’t know much about JavaScript but you usually packages all your files together before deploying it. So the fact is you are embedding the functions only once in the final bundled file.

        So, you never won’t download 20 separated files.

        Reply
      2. iraldir

        obviously everything is package into one one file at build time, so no 150kb is not better than 20x 0.5kb

        Reply
      3. Crubier

        “Also, including 150kb is still better than including 20x 0.5kb. http overhead can be ridiculous nowadays.”

        You are wrong. Modern JS applications are packaged in one single file, so there is no overhead. (Look up Webpack and Browserify).

        AndI agree with what Ian said above. This micro package thing is very good because it respects the DRY principle.

        Reply
      4. Tom

        No, front end tooling such as webpack that makes use of npm works the other way around. Rather than trim what isn’t used, start with lots of small modules and build them into only what is needed. This is why small, reusable modules are a very good thing for client side development. Sometimes these are modules you have written yourself and sometimes they are third party dependencies which IMO should be limited to those that you can absolutely trust.

        Also I think you misunderstand. The small modules are not deployed as small modules that each gets loaded as an independent asset. I agree that would be madness. They are built into a single package – or multiple chunks that can then be lazy-loaded at the appropriate point.

        Think of npm modules as small, reusable building blocks. The whole point of npm and modularisation is for things to be small – and yes that sometimes means a module being a single function makes absolute sense.

        Reply
      5. rasenplanscher

        > Also, including 150kb is still better than including 20x 0.5kb. http overhead can be ridiculous nowadays.

        Yeah, that’s why you should have concatenation in your build chain.

        Reply
      6. Samuel Reed

        There is – now. But there wasn’t a very short time ago, and many packages still need to change their internal structure to support it.

        Rollup & Webpack 2 can do tree shaking (dead code elimination… but actually more like live code identification) because of the static nature of ES6 modules. The previous CJS (`require()`) convention made it very difficult to do this effectively.

        When ES6 modules become more mainstream, I think we will see a larger death of these simple modules in favor of large utility libraries like lodash. It will be perfectly reasonable to install lodash just to include something like `_.padStart()`, because:

        1. It might be included elsewhere in the project, so installation cost is literally 0, and
        2. For browser bundling, the 40kb+ module can be reduced to < 1kb as unused code is removed.

        This will go a long way toward restoring sanity.

        Reply
    2. Tom

      This absolutely! What everyone seems to be forgetting is that we are talking about client-side code. It’s in our interests to make it as small as possible. So you can’t compare it to .NET for example where it’s perfectly fine to include an entire trigonometry library even if you end up using only a single method.

      There is nothing wrong with small modules as dependencies e.g. the lodash modules. They may independently do relatively simple things that yes you could write yourself, but as a whole they are a well used, well maintained, well tested, well documented set of core modules, so if you need more than one or two functions, then why not use them? It doesn’t make you a bad programmer to do so.

      Small modules allow tooling such as webpack to optimise the built size of your deployed JavaScript assets. They are generally a good thing.

      Size is not the problem here. What is wrong, is being dependency happy and using any old module. You have to be able to trust the source of your dependency. Does it have good tests? Does it have an active user base? And I agree that perhaps npm needs to make it harder for much depended-on modules to simply be removed without a very good reason. If something was published as open source to npm then perhaps npm needs to take ownership of it.

      Reply
  6. David Arsenault

    Amen. Very well said! This trend is actually insane. Dependencies should be used WHEN NECESSARY not just because you can find a one line or one function package. What you suggest here is very reasonable indeed. I integrate small functions from across other libs in my current C dev work (high perf computing) rather that take on dependencies. Dependencies represent several flavors of risk: risk of external code breaking me, tail risk for code maintenance, unknown performance risk (what’s that code do inside?), and messy mental model risk for understanding code with different APIs, naming, etc.

    Reply
    1. Crubier

      Have you ever heard of DRY ?

      Why should EVERY JS programmer bake their very own version of widely used functions, when battle-tested implementations are available using ONE npm install command ?

      This trend is actually the very thing that causes the success of the JS ecosystem, whether you like it or not. If done well, dependencies do not create the risks you are talking about. These risks are just the result of poor dependency management.

      Reply
      1. jsprogrammer

        Are you seriously defending single line NPM module usage by calling them DRY? No one is contesting copy pasting swaths of code instead of using a library but this “trend” in the Node community is plain stupid and reeks of unfamiliarity with basic software development practices.

        I can wager 90% of the folks using NPM modules won’t even know what “DRY” stands for…

        Reply
  7. Freddy Rangel

    I call this kind of attitude the “Tea Party” of JavaScript development. The reason why we currently have JavaScript tooling fatigue is exactly because Tea Party developers insist on writing everything themselves instead of trying to build a better abstraction. The lesson here isn’t not fewer dependencies: it’s managing dependencies. NPM should not allow someone to arbitrarily remove modules that other’s may be depending on. It’s like building a bridge and them deciding to remove it after a whole city now depends on it.

    Reply
  8. Jamie

    We haven’t forgotten how to program. We’ve just got better tools for sharing things we use a lot. You see one 11 line function. I see one of hundreds of such things that I will need in lots of different projects, and prefer not to reinvent, unit test, and maintain independently in each place I use it.

    Once you’ve decided to take code reuse and versioning seriously, instead of just having an organic, unique junk drawer that grows in each project, with untested edge cases lurking around every corner, and each project havibg slightly different implementations of nearly identical tools, you will realize that this is actually very sensible. We just never had a package manager that was so lightweight it didn’t get in your way, and it was actually worth creating a package so small.

    Reply
  9. Pingback: NPM & left-pad: Have We Forgotten How To Program? | Collin's Code

  10. Jamie

    .. Also this has nothing to do with creating small footprints. NPM was created for node, it’s adoption for use in client work is very recent. It’s philosophical. Bundling lots of tools in a big monolithic package is something we always just did, because pacakagr management was hard. If it was invisible, why wouldn’t you want to treat to every thing with no actual coupling to something else as a unique entity? What’s the rationale for large packages of things that you might mostly not need?

    Reply
  11. Pavneet Singh Saund

    Small re-usable components are exactly the point with npmjs.

    JavaScript may be lacking when compared to other “standardised” languages with large footprints, but that is part of the charm of being able to build up your app using the dependencies you need. I think Sindre put this quite eloquently in his “post” on the topic.

    But I do agree with you on being responsible with your dependencies. Add and use them deliberately based on your context.

    I wrote a post on this myself: http://codingwithempathy.com/2016/03/23/moving-past-the-hate-in-the-community/

    Reply
  12. Dylan Beattie

    “In every other language I have ever used, string padding is either built-in, or it’s part of a standard runtime that’s available locally on every workstation and build server. But not in JavaScript – if you want to pad a string in JS, you either write your own function, you copy & paste one from StackOverflow, or you import a package to do it for you, and based on the fallout from yesterday it looks like a lot of people went for the package option.”

    http://www.dylanbeattie.net/2016/03/how-to-really-break-internet.html

    Reply
  13. Jorge Chavez

    Today a friend of mine told me about what happened with NPM and I didn’t know how small was the dependency that you are talking about. I mean, 11 lines of code for a dependency, that just does not make sense. I think that it was a bad move for the guys of React or Babel and they will think twice before make a mistake like that again. I sometimes try to not depend in third-party libraries, or at least I try to install the ones there are a community behind of it.

    Reply
    1. Peter

      Uh yeah, that’s a hard one. But the thin is, given it’s license you cannot simply reimplement that function yourself 🙂

      1. The origin of this software must not be misrepresented; you must not
      * claim that you wrote the original software. If you use this software in a
      * product, an acknowledgment in the product documentation would be
      * appreciated but is not required.

      Oh dear …

      Reply
  14. Eric

    Why would you want to install a 500kb dependency that has only one function you need, when you can install a 10kb dependency that has it?

    Would you want each of your five 20kb dependencies to re-implement the same 5kb function, increasing the code you must send to the client by 20%, or would it be more optimal for each of those dependency to use the same 5kb function?

    The author comes from rants about practices of developers from different programming environment, without experience, without figuring how things came to be in the first place. If he did give an effort to think from the perspective from Node.JS developers he’d have addressed the previous two points.

    This is like going to a friend’s house and complaining everything is put in the wrong place. It would have been wise to immerse in Node.JS conventions and observe for a while before making comment.

    Reply
    1. Michael Youssef

      Well said, was just going to say that.

      Seems like he only talks about “Programming”, and know nothing about code reuse to resource packaging for the web.

      Reply
  15. Jamie

    One final observation about this fray. In the aftermath a hundred people posted one liners and said see? Why would you use some package instead of just inlining this simple code.

    Yet of all the ones I saw come across Twitter, every one failed the unit test in the silly 11 line module. Because they forgot about common use cases such as non-string operands or omitted the default spacing character.

    Even 11 line functions need to be tested. Even 11 line functions have non trivial features (such as an optional parameter) that you might want. Now you’ve got an API that you need to replicate everywhere you reinvent this thing, or confuse your developers.

    Why decide to not use practices that apply to your major work – testing, consistency, reuse – to a single function? Just because? The only argument seems to be “because I can easily rewrite it”.

    Almost all substantive code is composed of a lot of things that you could easily rewrite. How much more productive can you be if you don’t have to rewrite all that every time?

    Reply
    1. Anonymous Coder

      Fine, here you go:

      function leftpad (str, len, ch=’ ‘) {
      return Array(len-String(str).length+1).join(String(ch))+str;
      }

      That passes all the unit tests contained in that package.

      Understand that it is legitimate to complain about how bad a piece of code is (and face facts, that leftpad code he has is pretty bad), especially when it’s used by so many projects. This sort of code-reuse is only good when the underlying code is good as well. Making bad code is a problem no matter how you slice it.

      Reply
      1. Jamie

        The point isn’t that *you can’t write a working implementation*. Of course you can. This is about sharing code, not about whether you happen to like the code he wrote.

        If you want to publish your arguably better implementation and publish it under @anonymouscoder/leftpad then I would applaud you for embracing code reuse.

        And since it’s API compatible with “left-pad”, it’s really easy for me to start using your new, better implementation if I want to! Everyone wins. (Technically, though, your version is not the same: if I pass it an object, it crashes, instead of converting it to [Object object]. But since that wasn’t unit tested in the original, I’ll give you a break).

        None of this would be possible if you just inlined your own version of everything though. If one day you realize you need “left-pad” to be resilient when passed an object, you can’t just update it in one place and be done. You’ve probably got dozens of different versions floating around in all your projects by that time.

        Reply
      2. Ed

        This, also, misses the point. The point was that all the people complaining about how trivial the module was and how they could write their own *couldn’t*.

        Of course there are people (you being one) who can write a correct implementation. That in no way changes that other people couldn’t and didn’t. Thus, they would have been better off using the module.

        Reply
  16. tiwen

    Another insane thing is NPM uses caret versions (^1.2.3) by default. Caret versioning means you’ll always get latest minor releases instead of the EXACT version when you installed it.

    Using caret versioning means blindly trust any 3rd party developers are honest and will do their job right. Unfortunately, there’s one time that babel-core shipped a broken patch and the production system at my company went down for several hours. How ridiculous!

    Any when I try to bring up this to our JS “programmers”, they seemed to think this is OKAY.

    Back to your point,
    YES, there are tons of NPM users who actually don’t know what programming really is.

    Reply
    1. passcod

      Wow, your production system went down because you don’t test your builds before deploying them to production? Incredible!

      Reply
      1. tiwen

        sorry I mean it won’t build (testing failing for no reason, we had to examine every dependencies and finally realize it’s about babel-core.)

        Reply
    2. Michael Youssef

      You can use npm shrinkwrap to freeze stable versions, and then update them when you are comfortable with the updates.

      Reply
  17. Pingback: One angry programmer almost broke the Internet by deleting eleven lines of code (MSFT) – Rhetoric News

  18. Tex

    I’m sorry, the philosophy that packages should be building blocks like lego pieces diverts attention away from the fact that Javascript is a terrible language.

    As someone pointed out in defence for small packages, it has an inadequate core, but that’s just part of it’s problem. The sheer amount of code, packages, front end frameworks, languages that compile into javascript obfuscates javascripts plethora of issues. There’s a huge elephant in the room yet no one can see it, they’re too busy building an ecosystem to hide the elephant and shout “see? javascript IS a serious language!”.

    Honestly, this post is DEAD on. And it’s the reason why javascript should never EVER be run on any server doing any serious work.

    Reply
    1. Jared

      Agreed, except for the last point. It is reasonable to run Javascript on the server, even for serious work. Just stick to your own libraries, and watch other dependencies very carefully. Javascript can also be quite useful for those who want a scripting language, but cannot find any joy with (ba)sh/Python/Ruby/Perl/etc… And some of this can easily be ‘serious’ work!

      Reply
      1. Dustin Voss

        It is NOT reasonable to run Javascript on the server. It isn’t strongly typed, so you only find out about issues at run-time. It doesn’t have a robust debugger. It isn’t multi-threaded. It (and its packages) are poorly documented. The poor quality of its documentation is made worse by how the language and its so-called standard libraries are fragmented across browsers and servers. And the language itself is designed like shit.

        Some of these issues are shared by other scripting languages as well, but Python and Ruby are at least well-designed and consistent.

        Call me a curmudgeon if you must, but a language like C# or Swift or Dylan or even Java is simply better.

        Reply
        1. Jamie

          “It is NOT reasonable to run Javascript on the server. It isn’t strongly typed, so you only find out about issues at run-time”

          So your assertion is that STATIC typing protects you from all runtime issues, and there is no way to detect any issues before runtime in non-statically-typed languages?

          That’s rich!

          Reply
        2. Tex

          The fact that is a dynamic language is not the problem. You’re WAY off the mark there. There are many robust dynamic languages, Python being my go to, Ruby a close second. In fact, I don’t remember the last time I’ve used a “strongly typed” language, they’re best avoided unless needed for their features.

          Javascript’s problem is that it has some serious flaws in the language itself, and as everyone has pointed out, does not have an extensive core (like Python or Ruby). As a result, there is no cohesion in the community and everyone is left to run amok to do their own thing.

          It’s unfair to say Javascript programmers are bad programmers, but I think the author was being a bit ironic. On the other hand, Javascript developers they are deluding themselves if they believe that it is a serious language. Many younger developers that have recently entered industry don’t remember the time when Javascript was derided, that it was a necessary evil, and adequate enough to do some things on the browser. Prototype came along to make it suck less, and jQuery emerged to make it suck even more, but these frameworks came about because Javascript just flatly sucks.

          The fact that people run web servers with nodejs now is mind boggling. Javascript has made many astounding leaps in the last 15 years or so. That’s why under my watch, nodejs will never run a serious application on a server, simply because the language itself is flawed.

          Reply
          1. Lord Rybec

            Why do people who claim to be programmers not understand that “static typing” and “strongly typed” are two different things? Python is both dynamically typed and strongly typed. If you have been using Python recently, then you certainly should remember using a strongly typed language.

            Let me explain:

            There is statically and dynamically typed.

            Statically typed means a variable cannot change type, once it has been given a type. In C, C++, Java, and similar languages, this is done by declaring a variable to be a specific type. In Haskell, a function is typed implicitly based on its return type and how it is used.

            Dynamically typed means that the type can change. In Python, you can take a variable that currently contains a string and assign it to an integer. Most scripting languages are dynamically typed as well.

            There is also strongly and weakly typed, which are totally different from static/dynamic.

            A strongly typed language prevents variable types from being misused with other types. For example, in Python, you cannot add a string to an integer. This is what strongly typed means, and it has nothing to do with whether the variable can change types dynamically or not.

            A weakly typed language allows type misuse, often by implicit casting. PHP is a an example of a weakly typed language. JavaScript is as well. The problem with weak typing is that when you do ‘a’ + 1, you end up with ‘a1’, when you thought the variable containing the ‘a’ was an integer or the variable holding the 1 was a string, and now you have a runtime error that is extremely difficult to find.

            Research has shown that dynamically types languages (like Python) are often much faster to code in than statically typed languages (like Java), without significantly more errors (the primary argument given against dynamic typing is that it is more prone to errors, but the evidence does not support this claim). You don’t need research to see that weakly typed languages are a problem. PHP and JS, and the loads of poorly written programs that would have been saved with strong typing are evidence enough. And, if you happen to use these languages regularly, you will also be aware of the fact that weak typing make debugging take many times longer.

            The problem has nothing to do with dynamic or static typing. Dustin said that the weak typing was a problem, and it is. Weak typing has been a problem for PHP developers for decades, and it is an equally annoying problem with JS.

  19. mat

    “rather than taking 2 minutes to write such a basic function themselves”

    Sure I can write the function in 2 minutes. On this project, and then the next, and then the next. But why don’t I turn it into a utility package and include that in each project instead?

    That said, these packages are crazy small.

    Reply
    1. Flo

      Yes, and having dozens of “crazy small” dependencies add a layer of complexity that is not “crazy small” anymore. If you had one or two library-dependencies that include much stuff (like Apache Commons in Java), ok, but bloating your project with dozens of dependencies for every little bit of code does not reduce complexity at all….

      Reply
  20. Peteris Krumins

    My advice to “prefer core-language solutions to small abstractions to small helper libraries to general libraries to frameworks” (http://bit.ly/1UlQzcH) hasn’t been more relevant than today.

    Software should be developed using least amount of complexity, dependencies, effort and using fundamental tools that have been and will be here for the next 20 years. Cut those dependencies, you don’t need them. They’re here today and won’t be here tomorrow.

    Reply
    1. Sam

      And yet you are not right today and won’t be any day in the future.

      Dependency Management has worked for dekades now. See APT in the linux world. It has worked in the past. It will work in the future. But there will always be a few days of trouble in between. That’s perfectly normal and it is perfectly fine. All we need to do is find solution and agreements as to how we solve these kind of conflicts in the future.

      Constantly re-inventing the wheel by writing stuff yourself is just utterly wasteful.

      Reply
  21. Alex Schleber

    BTW, the toString.call(…) is slow as hell, and will over many fn calls using this waste you a ton of performance.

    Better to use
    if (testvar.constructor === Array)…

    Or do
    switch (testvar.constructor) { case Array:…; case String:…; … }
    etc.

    No slow generic Class Function call, no expensive string comp, all pointer comparisons only…

    Reply
  22. Pingback: One angry programmer almost broke the internet by deleting 11 lines of code (MSFT) – Rhetoric News

  23. javascript

    The comments here show a real ignorance of the history of Javascript.

    First thing to understand: Javascript code runs in a TON of slightly different implementations. IE8, IE9, Safari, Node, SpiderMonkey, whatever the fuck. Oftentimes this is fine and you can ignore every other implementation but the subset you care about. But sometimes you will want to reuse code across a shitton of these environments (THE SITE DOESNT WORK IN IE8 screams your boss), so you write your “5 minutes of code”, *YOU WRITE SOME TESTS*, and you test a bajillion times until your tests pass everywhere and your code is performant enough and you never have to do that again, whew. THIS IS NOT AS EASY AS IT SOUNDS.

    That is what you’re seeing here. This has nothing to do with modern Node or Javascript code. `isArray` is a polyfill for Christ’s sake. No one *ever*, *ever*, *ever*, should want to rewrite polyfills, but they have their place for the sake of compatibility. Blame it on the IE8 user percentage.

    So yes, Javascript, across a billion implementations and environments, can be extremely ugly. How could it not be? It is clearly getting better, and as we slowly move forward and shake old implementations, it can only improve.

    Moreover I think your general point is completely wrong. Yes these are small modules, but modularizing everything is the only way to go. The other route – rewrite it in 5 minutes every time! – clearly breaks down fast. Copy and paste my code, then copy and paste the tests into the test suite (if you’re writing code without tests, you don’t get to have an opinion). But then a month later you notice a small bug in some corner case – padding a String to a negative amount goes into an infinite loop! And you fix the bug, add a test, but now you have 5 other copies to update, with no way to keep them in sync. Good luck with that. I’ll be over here, with my modules, running correct code.

    Reply
  24. danderson00

    All of a sudden, everyone is an expert on software process. So many misinformed and just outright wrong opinions.

    Reply
  25. Pingback: One angry programmer almost broke the internet by deleting 11 lines of code (MSFT) | Who Runs The World

  26. Robert Fletcher

    Dealing with the deeply nested dependencies has caused us no end of frustrations. A dependency of a dependency of a dependency breaks and we’re left trying to trace the source of the error and figure out which repo to open an issue on. I don’t particularly care to have it in our codebase either, though, unless it’s something that I want to heavily modify and maintain myself. If I’m developing an application, utility libraries like underscore/lodash are a huge boon, or the likes of ActiveSupport in the ruby ecosystem. You can require in just the parts you need without having to bloat your dependency tree.

    It’s a little different as a library developer than an application developer, though. I’d say if you’re a library developer, you can do your users a service by including a little of the extra utility code in your library rather than adding extra dependencies. You aren’t really saving space when you’re downloading the extra boilerplate anyway.

    Mike Perham discussed this topic recently, too:
    https://www.mikeperham.com/2016/02/09/kill-your-dependencies/

    Reply
  27. Marvin

    I thing you are wrong. Other languages hide that sort trivial complexity you are pointing at in their Standard libraries (take e.g. Python or C++). JavaScript does not have that for whatever historic reason. The problem is more the whole npm system and how it works.
    And beside that my main job as programmer is not to just to program… it’s most of the time not reinventing the wheel again and again. Reinventing programmers are not good programmers for me. I’m sitting on the shoulders of giants and I want to solve problems while programming… it does not mean I don’t know how certain things work.

    Reply
    1. pq

      When you have to implement some function you may either implement it yourself or look if there is an implementation by someone else that you can find and use.
      This second process involves these steps:
      – look for one or more libraries which implement the functionality you need
      – investigate these libraries to see if they do what you expect and they are good enough for you to use (for example, are they being maintained? Do they depend on something else in order to work? Does the same quality standards apply to their dependencies?)
      – add them to the project, and maintain the dependency (for example, update to new versions when needed, eventually fixing the code when the functions you were using are removed from the library or deprecated, replace the library with some other would the above condition for its inclusion become false)
      – learn which functionality the dependency included has, so that next time i need something that is available there I won’t add yet another dependency, doing all the steps above.

      If the included library is a single function with a simple algorithm which could be written in theory in about 30 secs, why people are taking the effort to even think about looking for a library? I have some theories:
      1) you need a lot of such small function, and you hope to find them all in a single library, or
      2) you are not really doing all these steps, in particular checking the quality of the library yourself but you trust the number of downloads, maybe also because
      3) you can’t really write that simple function, or at least not in 30 secs, and thus you can’t even understand whether the library you’re including is good quality, and your usual strategy of asking on StackOverflow for people to solve your problem will likely take longer and is better to reserve this card for your “real work”.

      Some final rants:

      – It is not about reinventing the wheel, the wheel is not even needed here because the objective is at 30 second walk from you. Unless you need them for your wheelchair, in that case yeh I suggest you buy them instead of trying to build them by yourself.
      – DRY is “don’t repeat yourself”, not “don’t repeat others”. It doesn’t mean you cannot write your own code if someone else wrote it for you, it means that you should not write it more than once.
      – To stay in topic, there is another design principle known as KISS, which you may know. Dependencies create complications, conflict, code bloat, increase the number of points of failure. Lot of small dependencies from different developers decrease overall coherency of the system, may not work nicely together (or not be tested to keep working nicely together with future updates), which is something whomever used lots of LaTeX packages in the same document know by experience. Is it better to avoid them unless necessary.

      Reply
  28. Guy

    It was a delightful experience reading all these comments and watching my internal opinion drift back and forth as each writer had their say. I want to thank the entire community for all I learned during that process.

    I have to agree with many who point out that re-writing functions, especially tedious functions, is not DRY compliant. On the other hand the exercise of our art as software engineers, designers and computer scientists is often improved when we take the time to focus on the basics of what we do and take it upon ourselves to understand as well as be able to perform the steps of implementing and testing what should be easy, straight-forward tasks. It is often in remastering something we thought we already knew that new insights are generated.

    Reply
    1. Steve

      It really is a matter of where one chooses to ‘cut nature at the joints,’ isn’t it?

      Throughout the preceding rhetoric around, ‘where did the art of programming go?’ I didn’t notice anyone argue for pushing and popping registers in assembler, or painting screens with memory-mapped displays.

      It seems we are merely experiencing the next batch of growing pains, as the ‘art of programming’ shifts from inventing to re-use, from managing algorithms to managing [micro]codebases — and importantly, how to strike the balance given current realities.

      Reply
  29. Diane Trout

    And the NPM world thought the Debian developers were too old fashioned because they wanted a build system that “compiles” minified JavaScript filesfrom packages that have source files installed someplace helpful like /usr/share/javascript/

    Yes JavaScript doesn’t have a standard library and so you need an amorphous composable library, but seriously, have a build process that can succeed without needing network access.

    I might suggest at least being able to say dependency X-1.2.3 is in this directory and that dependency Y-2.4 is in this other directory

    Reply
    1. Peter

      Interesting! I wasn’t aware of this Debian / NPM situation. But Gentoo had a similar discussion with PHP Composer and result was the same. Composer is awesome by design and Gentoo should change.

      Reply
  30. Tarun Elankath

    If I write my own lpad function, I then need to write unit tests for this function. lpad is only one function – there can be dozens of other such ‘micro’ functions. In the ideal world, the JS standard library would have all such frequently used functions, but it is not an ideal world. The reason for the hyper-modularization in the JS world is to avoid pulling in large modules that increase file size. It would have been so much better if all these super commonly used micro functions became part of ES7.

    Reply
    1. MacK

      Are you seriously thinking about integrating unit tests for a 4-line piece of function which will sit there for an indefinite amount of time untouched? Seriously?

      Reply
      1. Lord Rybec

        Exactly. If you are such a poor programmer that you need unit tests for a 4 line function… Honestly, I don’t know what to say.

        For small functions that do trivial things, you manually test once, and then you walk away. “What if you need to change the function?” I hear. If that is the case, then it is either not trivial, or you are trying to add functionality that does not belong in that function.

        I think, perhaps, part of the problem here is that people are trying to take unit testing down to a level that is way too small? Are you ever tempted to compile to assembler and make unit tests for individual lines of assembly code? (If anyone reading this just said, “Hey, good idea!” no, it is not a good idea.) Neither am I, and I’ll tell you, this is what it sounds like they are expecting.

        Besides that, if it is so hard to write a unit test for a 4 line function, then perhaps you should start looking into jobs in a field that is less strenuous.

        Reply
  31. Robert

    Just a simple economics. The world out there needs X developers, universities can only produce Y. When Y < X people with some knowledge, but maybe lacking formal education or experience are tempted to take a chance. Which is a good thing. The problem is, the pressure from the market does not allow them to learn, instead they do junk coding. Like a junk food, for a short span of time it may be harmless.

    Reply
  32. Bahadir Yagan

    Nothing is sane about having a dependency whose code is smaller than it’s sha1 hash. That package has an additional 6KB overhead with readme, packages.json and a license. Not much for one package but an empty react project has 600 of those packages. Prior to npm3 those were downloaded recursively multiple times. I remember one time my node_modules folder was at 300K files and 1.2G size. JS is great, but npm is shit.

    Reply
  33. Pingback: One angry programmer almost broke the internet by deleting 11 lines of code (MSFT) - Funny web, funny life | SampleFun.com

  34. Pellaeon

    When you’re coding, it’s often mind-bogging to leave bebind the entire big structure etc, and to focus on writing that function that does simple left-padding. I often hate it because you have to leave what you’re doing at the moment and dig down to the lowest level of details to write that left-pad function, which programmers in the world should have solved it a million times.

    And if you decide to not code left-pad by yourself, is it better to copy-paste that function from StackOverflow, or to include a module?

    Reply
    1. Lord Rybec

      For 11 lines, copy/paste is better! For a single small function, if its current implementation works for your project, and if you can easily tell that the code is not malicious or buggy, copy/paste it. The biggest benefit of including over pasting is that you get bug fixes with a simple update. No 11 line function should be so complicated that you cannot tell if it is buggy or not. (And if it is too complicated for you, you should consider that you might be a bad programmer.)

      If you need 100 small functions, something is probably wrong, but if you insist, put them in a separate utility file and go from there.

      Reply
  35. Pingback: Dependency hell | Wolvnet

  36. slw

    Is nobody even going to point out the fact that the left-pad implementation is wrong?

    It assumes that ch has length 1, if it is longer, it pads the string to an incorrect length.

    Also, it’s seriously slow, all those string concatenations…

    Reply
  37. Pingback: Инцидент с захватом прав на NPM-модуль привёл к сбою в работе проектов, использующих NPM | AllUNIX.ru — Всероссийский портал о UNIX-системах

  38. Georg tenchu

    THIS STUFF NEEDS TO GET INTO ECMASCRIPT!
    it’s a a shame for everyone involved, how js handles such easy things

    Reply
  39. Hok Shun Poon

    Programming with the Internet is a superpower.

    Programmers are those who don the cape,
    Have an ambition to build what never existed before.
    They spread their hand and raise it to the ethers of FOSS
    Summoning code blocks from NPM and StackOverflow
    To assemble what they wanted to assemble at lightning speed
    And gets a kick out of seeing their little creation spring to life.

    There is no one way to do it.
    Some might write the implementation of isArray inline a thousand times because ‘they know how to code’ (where in fact they just know how to fill the bits missing from Javascript).
    Some might write it themselves and use that function every time.
    Some might be using lodash anyway so they go use that.
    Some might have better things to do than to learn about the inadequacies of Javascript, and find that grabbing the isArray dependency from NPM the way to go because it’s got the lowest conceptual gap (I don’t know how to do X… well there’s an NPM package called isArray that does X for me. I’ll grab it, problem solved). Who can honestly say they haven’t done this before?

    It’s all the same — it’s different ways of copying and pasting strings into a code file, or into your brain, as the case may be. It’s all gibberish for the computer at the end of the day, and some approaches are better than others.

    Reply
  40. Pingback: NPM & left-pad: Have We Forgotten How To Program? – Peter Molnar

  41. ajuc

    Why on earth writing that trivial piece of code 10000 times by 10000 people would be better?

    I’m not even javascript programmer (I mostly do J2EE and C++/qt), but I think npm got it right. It’s not bloat if you depend only on the functions you actually use.

    Reply
  42. Pingback: Dependency Hell bei Node.js

  43. mrmoo

    This has probably mentioned … I read the article but skipped the comments:

    Great observation; I don’t believe we should put this down to NPM/Node/Javascript engineers as the problem. Yes this is a bad symptom of a great ecosystem, however if you choose to build your house by the sea; its your fault if you ignore warnings e.g. tsunami, tourists 😉 etc …

    As a team / org / opinionated perfectionist, set up a private registry and snapshot your deps. Don’t rely blindly on what you know can break; because it will.

    Reply
  44. Kubatko

    Seems totally valid to me to take such dependency, at least you have kind of thousands of other eyes looking after that one line of code.

    Packages are just word and it’s up to you how you define it, they can contain complex functionality or just a line of code.

    Reply
  45. redhoodsu

    Usually when a small utility function is needed, I go directly to the repo and copy the code into my util library. To me, install a package merely for a single function is really strange. Luckily, I just wrote a tool that happened to solve the copy paste problem, you might be interested in it: https://github.com/liriliri/eustia

    Reply
  46. ower

    I always though that the small packages in npm were that what because it used for the web and if you are using just a function you don’t want to import a massive library because it will negatively affect the site loading speed.

    Reply
  47. Pingback: NPM事件引發瞭代碼復用的爭議 | Comeposts.com

  48. Pingback: NPM & left-pad: Have We Forgotten How To Program? | thoughts...

  49. Tameem Safi

    “Do you make your own shoes? No, you buy them in a store. Most don’t care how the shoe is made. Just how good it fits.”

    I can’t put it better myself. Even though something may seems so small and insignificant, a lot of work has gone into creating it.

    Therefore, instead of copying it or writing your own version it is better to use modules as they can be updated once and then would work on all other packages that require it.

    Reply
  50. Nobody

    Sorry, but i also think you should be getting down off your high horse.

    Programming is about creating stuff, not re-inventing the wheel 100 times. For dozens of years, developers re-implemented all their stuff (all except the standard libraries, e.g. stdc) constantly , because sharing of libraries was difficult. Now its easy.

    The real issue is using javascript as programming language. Checking if an integer is greater than 0 should be written “if(var > 0)”. The packages you mention, like isPositiveInteger or isArray, provide simple functionality which should already be integrated in JS itself.

    You are saying “everyone can write it himself in 5 minutes of googling”, but i think you are not realizing what you are saying. Developers should copy paste code from stackoverflow? How about updates and bugfixes? Or you say “you have to write it yourself”, but just look at your examples of isPositiveInteger or isArray. Look at it very closely. This is not code which is developed, this is code which accidentally works and returns the correct result in most cases (for most JS implementations). This is not code which developer cannot and should not create by themself.

    Dont get my wrong, the JS and NPM situation is a bit a mess. But your conclusion is still wrong.

    Reply
  51. Pingback: Around the web: Episode #2 | GX Consultancy – Blog

  52. CarbyAu

    I don’t program, but it strikes me that this is DLL HELL all over again…..

    Personally, I would modular dependencies should be a considered decision.

    Upside, get to reuse code (which last I heard was a good thing)
    Downside, control over said code…

    There is no right answer for all situations personally I would lean towards removing dependencies where possible.

    Reply
  53. Jimmy Olano

    The Go language (I am not fan) give error when you declare a variable -or other thing- AND YOU DO NOT USE IT AFTER.

    That’s common sense, however I see maybe obfuscated code won’t work (if you use open source, why obfuscate?).

    First that, and another thing: if a function or module is so popular, GitHub may implement some statistics about it for a human read it (indeed, this article is about that).

    My point is: let’s incorporate that module -very popular- to the language; I call it “canonize it”.

    “Canonization” will be done by hundred of eyes and garantize it works well. Of course, we must publicite the new version for everyone’s knowing: if you want continue using your own -or other- modules you are entirely free.

    Final point: if you are a programmer your users will talk with you at any mistake -however they NEVER give you a congratulation when all is working fine- and the other hand they never will understand that you are using code from other programmer. You are alone in this, Google won’t help you.

    Happy day for everyone. 😎

    Reply
  54. Szymon Stasik

    After reading various argument the main conclusion for me is that while it is good to not reinvent the wheel and have ability to use even simple helper functions then on the other hand it is insane to have separate module for any single (or even couple) line of code.
    Looking not that far on somehow more mature OS development environment – there are also common libraries, like i.e. glibc, however they are aggregating many various common things. Now I wonder why this is has not happen in the javascript/node/npm to develop similar common core package(s)?

    Reply
  55. Rob

    Unequivocably yes! It’s why I always get downvoted into oblivion on amateur sites like Reddit where any mere mention of learning how to code instead of piecing together other people’s code is scoffed at and made fun of while making funny sentences out of random words using javascript is front page news.

    Among today’s programmer’s, far too many are trained by scouring the web and composed of people who find making programs (more often games) exciting and not a thought process. Those who want to do it right are made fun of with “don’t reinvent the wheel” or “why do it the hard way when you can just use a package?” type thinking.

    Such people never learn how computers really work and, typically, trail behind adapting new technology if they are in the industry at all three years later.

    Reply
    1. Yimi

      Ok, continue redoing, copy pasting, the same code over and over in each project you do, that’s right, reusability, modularity is just a fashion made by bad programmer.
      You should also duplicate your code, that the good way.
      Then patch it, because in some environment your awesome duplicated homemade function doesn’t work.

      Reply
      1. John

        Well, while I’m not 100% OK with his entire comment, there’s some truth in it, like “don’t reinvent the wheel” and stuff. Sometimes, it even feels like bullying and you do feel bad for the guy who asked in the first place…

        You know, the community and its pressure can really be shitty at times. Like when “just use jquery” was the most popular answer on stackoverflow a few years ago.

        Reply
  56. Kyle

    LeftPad is a **package**? Yikes.

    I have many thoughts on this, but its been a few years since I’ve done serious JavaScript, so my observations may be complete bunk.

    Let’s not assume everyone’s stupid.

    This is a symptom of a deeper problem.

    Cause 1: JavaScript has a feature-poor core library, and doesn’t include standard functions LeftPad.

    Cause 2: There is a lack of cohesion in the JavaScript community because of constant library churn. So there is no longer even a de facto standard library (sort of like the position jQuery occupied for years). If there were such a de facto standard package, LeftPad would get added to it.

    Cause 3: Javascript now appears to have a decent package system that makes it easy to install and use lightweight dependencies (I haven’t used javascript for a few years, so this is my impression).

    Cause 4: Who wants to gives the honest but foolish standup the next morning: “Among other things, I wrote LeftPad yesterday”. There’s at least one evil bastard on every sizable team. If you’re good enough to write LeftPad without thinking, you’re probably also more talented than the evil bastard. This makes the evil bastard itchy to find something to pin on you. You just gave the evil bastard a foothold… “You are not focused on the big picture”… “You are reinventing the wheel”… “Why are you not using the LeftPad package? It’s on NPM.”

    Reply
  57. Mikael Brassman

    While I do agree with the notion that npm has a “house of cards” problem, the assertion that people can’t bother to code a simple function like left-pad in five minutes is a “bad coder” is downright navel-gazing ego-boosting reasoning and totally glosses over the whole reason npm exists. Do you really want to be part of the JavaScript community that continuously verbally chastise programmers because they are “lesser humans” than you? I.e. the unhelpful part? I.e. the “bad part”?

    Reply
  58. Graham J

    So if lodash or bluebird packages become unavailable the problem is I didn’t write them myself?

    I agree it’s important to be able to do these things (if you can’t program why do you call yourself a programmer?) but time is money and different people draw the line of when to rely on a package vs. when to do it yourself at different places. Where that is isn’t the problem with npm.

    Reply
  59. farzher

    `leftpad` is a generic concept. You should not be writing this yourself.

    The only code you should be writing is application-specific code.

    Even the 1 line ` isArray` package is good. I might miss an edge case if I try to implement that nonsense myself (it should really be built into JS). That 1 line package has unit tests, performance tests, and bug trackers that I wouldn’t have myself

    We haven’t “forgotten how to program”; you’re being old-school and apparently haven’t learned how to program efficiently

    Probably we shouldn’t be dependent on NPM though

    Reply
  60. Ben L

    These are all fixable problems. Heuristics and analysis could detect these rancid packages if it the need arises. While for most part, the crowds have more wisdom in selecting value and nurturing projects in the open source community, a few outliers will need addition policing.

    The paradox of choice takes an order of magnitude to extreme when the number of packages and open source forks reaches these numbers. So curation and leadership remain important helping developers be successful in their decisions.

    I think the question about have we forgotten how to code is the one we keep asking ourselves every year for decades. I recall seeing an early assignment in jr. high school writing different sorting algorithms in BASIC, and thought to myself, hasn’t someone else already written this subroutine? Does every programmer need to write their own quicksort? Yes, and No.

    Reply
  61. Sinisa

    “Perhaps the real answer it to stop fetishising a 20-year-old language that was thrown together in a week, and make a concerted effort to standardize on something better.” – Jim

    So true.

    Reply
    1. Steve

      Not strictly disagreeing with the premise…. but may as well dump QWERTY for Dvorak keyboards while we’re at it.

      Reply
  62. Zach

    If we as a community could just get npm to stop downloading the whole goddamn internet any time I install a project with like 4 dependencies, that’d be great.

    Reply
  63. Erick J

    How is this surprising?

    The unfortunate state of things is that much of the node/npm community are a hangover of script kiddies from the JQuery and Rails cargo cults. Much of this same community can be found on stackoverflow and hackernews reinforcing each others bad ideas. Those arguing that dynamic/meta/duck-type/flavor-of-the-week programming isn’t scalable get voted down as being unhip or uncool or unknowing.

    8 years ago the cults worshiped Rails and Prototype/Scriptaculous with ERB templates (because writing your JS in Ruby was obviously the best). Then they used HAML and jQuery.UI. Then handlebars, but if you were really cool it was mustache (or the other way around?). Then the server thinned out and batmanJS sproutcore’d a backbone. Then someone lit an ember under angular. $ lost to _ and lodash, a bazillion other microframeworks. “Hey do you call .toString()” ever? Well use this toString-npm”. Then came the age of erlang/haskell/rust/Go because you have to design your tiny website from the ground up monadically processing your process trees for 1e9 QPS, just in case. Now we’re in the midst of React and Nodejs, because why wouldn’t you want to write in JSX and be limited to 1 core. Some of these trends last longer than others. Most turn out to be terrible

    I will continue to happily ignore 99% of these trends, sticking to more established practices.

    The question isn’t “Have We Forgotten How To Program?” it’s “Did we ever learn?”

    Reply
  64. Pingback: One angry programmer almost broke the internet by deleting 11 lines of code – Izon Inc

  65. Pingback: Michael Tsai - Blog - How One Developer Broke Node, Babel, and Thousands of Projects

  66. Pingback: Micropackages and Open Source Trust Scaling - PyBloggers

  67. Craig

    “rather than taking 2 minutes to write such a basic function themselves” Well, because that’s how you get fundamental security bugs. ‘Just write it yourself, newbs!’ is a poor argument.

    Reply
  68. Nanang Mahdaen El Agung

    I think depend on what we need. The `isArray()` package (for example) is something I (or we) use everyday on every projects. So better to load the existing one than re-writing for each projects. But, if we only need `isArray()` and we load Angular to get `angular.isArray()`, this is would be totally wrong since better to spend less than 5 minutes (I believe it should be less than 2 min) to write that code.

    But, we (developers) should try to understand our languages before deciding to choose which libraries we’ll use. For example, if peoples working on javascript projects and they load `isArray()` module, then probably they don’t know javascript, since javascript has built-in `Array.isArray()` (except if they work on very old javascript :D).

    So why micro modules exist? Because its help developers to get the daily use functions that do not exist yet. Like the `left-pad` module, if we have 10 projects that require that function, why we need to waste time to write it 10 times? It’s not (always) because we’ve forgotten how to program, but sometimes our boss say “You must complete it in 1 hour!”. But if we load Angular to get `angular.isArray()` while built-in `Array.isArray()` exist, then maybe we don’t know how to program.

    Cheers!

    Reply
  69. Pingback: More on “npm” leftpad – Win-Vector Blog

  70. Pattern-chaser

    Without wishing to detract from the article, what about DRY? Wouldn’t it counsel us to reuse what is already there instead of duplicating it?

    Reply
  71. Stibbons

    Node lacks a real standard library. I don’t want to recode such obvious code that isObject or how to iterate though some array because JS is so a bad language. So when I want to do it in JS, I just search if someone has done it already

    Node, and JS, needs a True Standard Library so developers can focus more on their real job rather than how to deal with flaw in the JS langauge

    Reply
  72. Pez

    I have seen too many projects with huge frameworks and external libs used to hide complexity that wasnt ever needed. Complex routing functionality used to present one simple view.

    Writing good code is art.
    Watch children drawings is nuttin but cute!

    Reply
  73. Amir Rahnama

    what if this package was a big one? Like Babel? or Like Mocha? what would you conclude then? Not to use less modules? I think your argument becomes weak when from the accident you are

    Reply
  74. Christopher

    Spoken like a true .NET developer.

    While you’re over here waxing philosophical and promoting Not-Invented-Here Syndrome, people using NPM and javascript are busy actually building things in a productive manner.

    I likely wouldn’t add those 11 lines as an NPM (although I’m not apposed to others doing so), but I sure as hell wouldn’t take the time to write every little helper function myself either to prove I “know how to program”.

    Reply
    1. Actual Programmer

      Spoken like a true front-end web “developer”

      Micro modules are bad, they promote not actually knowing how to program, and your idea of “building things in a productive manner” is really funny. Are you also a “10x developer”?

      Reply
  75. Tony Di Croce

    I had to know so I went and checked… is-positive-integer used to depend on is-integer and is-positive!

    Reply
  76. Nerot

    Everyone leaping to NPM’s defense with arguments like ‘a bunch of dependencies is better than every developer re-writing some code every time’ is missing the point. Get back to the discussion of whether it’s better to inline your own code or import someone else’s, after sorting out the obviously, painfully clear issue that a house made of dependencies IS going to fail. Sometime, someday, it will.

    And guess what? it did.

    Reply
    1. Peter Brooks

      Microcode, that’s where you really can program. Can you shorten those five lines of code to three, by adding pre-fetches in the rightmost two bytes so they can be snapped out of the pipeline in the third instruction?

      It gives a great feeling of control to be able to do so much in what is, to the untutored eye, one assemble language instruction.

      I was lucky to have the job of teaching some BT engineers to microprogram – the HP A900 had a very elegant micro architecture, and, best of all, you wrote the microcode in a high-level pascal-like language, you could pack multiple micro instructions into one word by the simple expedient of leaving out semicolons:

      a = b + c;
      If a > d then do x;

      Gives you two words

      a = b + c
      If a > d then do x;

      Puts them both into one word.

      Of course, the second might not work, unless you’d prefetched the ‘d’ earlier.

      Oh, and the beauty of it – at the same time you could have some floating point arithmetic going on – the FPL took three cycles to complete, so, if you were cunning, you could interleave tons of useful logic, instead of just waiting.

      The HP1000 had a sixteen bit word, but the micro machine had a twenty four bit word – plenty of space to express yourself.

      I really, really, must have enjoyed this at the time, to remember all this stuff 30 odd years later!

      Reply
  77. Scorpions4ever

    Was surprised that no one has yet commented that the original code is inefficient and has a couple of lurking bugs as well.
    1. There aren’t checks to see if str is undefined, null, Object, boolean etc. Ideally, it should only pad arguments of type string or number
    2. Why loop n times and construct multiple temporary string objects, when you can just use return ch.repeat(len – str.length) + str. Instead of constructing a bunch of temporary javascript strings in the loop and assignging it each time, the .repeat() call makes a single JS call to the interpreter to construct the string (which presumably calls much faster C code to construct the string) and then does one string append.

    Reply
    1. Anonymous Coder

      String.prototype.repeat() is new as of ES6. Meaning that it has only been around since last year.

      The more “normal” way to do something like that is Array.prototype.join(), which has been around since ES1 (1997).

      Reply
  78. Pingback: Micropackages And Open Source Trust Scaling | 神刀安全网

  79. rtpHarry

    People who are saying no to using these micro dependencies and saying we should write it all ourselves, I get it, when I first started I insisted on doing the Int13h programming myself instead of relying on Allegro. I wanted to write it all myself and do it properly.

    I hit lots of walls, and then when I started doing it professionally I didn’t have that luxury to solve each problem myself and take an hour to deeply understand the issue. I needed to get it done within a quote that my clients would accept.

    These days writing it all myself is even less of an attractive prospect because there are little glitches out there and more devices than we can test against. We might think we have solved the problem but maybe on platform X this gotcha appears and then our users get bad stuff all up in there faces.

    Its being touted as “left-pad broke the internet”.

    In reality millions and millions of npm packages are used all the time without problems. What actually happened was a couple of big packages has a couple of hours of mild disruption. It was a rare case occurrence.

    The XKCD I kept expecting to get referenced for this argument (debate) is https://xkcd.com/378/

    This is one of those debates that will never be settled because both sides are right for a given scenario.

    Reply
  80. Pingback: More on “npm” leftpad | r software hub

  81. max

    But the time I read down to “Functions Are Not Packages” I had formed enough counter arguments in my own head to stop reading altogether.

    >Functions are too small to make into a package and dependency.

    Where is the evidence for that? This little assertion is clearly proved wrong by the existence of Left-pad and isArray. haha

    I guess what the writer really meant if that it’s a bad idea. Why mean what you say and say what you mean. It’s sloppy writing.

    >Pure functions don’t have cohesion; they are random snippets of code and nothing more.

    Absolute bullshit,

    This is a random snippet of code
    “lorem.query = ‘2p’;”

    IsArray and left-pad do useful things.

    >Who really wants a “cosine” dependency? We’d all really like a “trigonometry” dependency instead which encompasses many “tricky” functions that we don’t want to have to write ourselves.

    For performance reasons (such as when loading Javascript code on mobile clients) you don’t want to load a large library when you only need one function.

    Reply
    1. smcfl

      You missed those points. And I bet you’re new to programming.

      >Where is the evidence for that? This little assertion is clearly proved wrong by the existence of Left-pad and isArray. haha
      >I guess what the writer really meant if that it’s a bad idea. Why mean what you say and say what you mean. It’s sloppy writing.
      The author is exactly criticizing that. And it’s not sloppy writing. It is just you are being slow to get the meaning.

      >IsArray and left-pad do useful things.
      Do you even know what cohesion is? It is not mainly about whether something does useful things or not.

      >For performance reasons (such as when loading Javascript code on mobile clients) you don’t want to load a large library when you only need one function.
      I partially agree here. But I think module bundler like webpack now can do like remove unused code.

      Reply
  82. max hodges

    But the time I read down to “Functions Are Not Packages” I had formed enough counter arguments in my own head to stop reading altogether.

    >Functions are too small to make into a package and dependency.

    Where is the evidence for that? This little assertion is clearly proved wrong by the existence of Left-pad and isArray. haha

    I guess what the writer really means is that it’s a bad idea. Mean what you say and say what you mean. It’s sloppy writing.

    >Pure functions don’t have cohesion; they are random snippets of code and nothing more.

    Absolute bullshit,

    This is a random snippet of code
    “lorem.query = ‘2p’;”

    IsArray and left-pad do useful things.

    >Who really wants a “cosine” dependency? We’d all really like a “trigonometry” dependency instead which encompasses many “tricky” functions that we don’t want to have to write ourselves.

    For performance reasons (such as when loading Javascript code on mobile clients) you don’t want to load a large library when you only need one function.

    Reply
    1. Laurent Hasson

      So, because JavaScript doesn’t have a “linker” system, you do these types of things? With that logic, all modules should be at most one function.

      Reply
  83. Pingback: The leftpad debacle | dorinlazăr.ro

  84. Namo

    How does someone removing a package from the website affect already built applications? Are applications constantly checking npm central?

    Don’t the packages remain as is once they are downloaded into the project?

    Reply
  85. Pingback: News de la semaine #13 | Sortir du chaos

  86. Pingback: QA Hates You » Blog Archive » Preach It, Brother

  87. Fagner Brack

    Stop thinking in a Object Oriented way and then you will realize that “trigonometry” doesn’t make any sense. Get only what you want without having to care about the environment you are in.

    Reply
  88. Jaime Torres

    What seems to be forgotten is when shimming JavaScript, it’s a lot like adding a C# extension in System package. Because you’re adding it to base-object prototypes, the ENTIRE application gets it, not just your namespace. So if I pull in angular, and bootstrap, and underscore, and my own package, and each of those needs a “leftpad” solution, and they followed this articles advice: there would now be four flavors of leftpad sitting on String.prototype. If each were 11 lines long, I now have 44 lines dedicated to left-padding a string. By importing a microlibrary, there is but one, and 11 lines of code. At this point, who forgot to program? The guy that doesn’t know how to leverage the works of others and build an application, or the guy who wants to reinvent the wheel that’s already been built four times in his application?

    Pragmatic developers aren’t stupid, they’re efficient.

    Reply
  89. Pingback: I’m not a programmer, but … | /home/kOoLiNuS

  90. Pingback: /home/kOoLiNuS

  91. Laurent Hasson

    We went from spaghetti code to spaghetti component dependencies. Computing “constructs” have an optimal size. I strongly believe that. One-line functions always bothered me, even with compiler inlining capabilities. Interfaces with one method, classes with one method etc… There has got to be a way to think about these things as an ROI system for example.

    Reply
    1. Ed

      Do they have an optimal size in terms of lines of code or in terms of functionality provided or in terms of complexity abstracted away? There’s nothing inherently right or wrong with a single line function if it saves you time to use it.

      Can you prove what this optimal size is?

      Reply
  92. Pingback: Micropackages and Open Source Trust Scaling | Tecnologia de mediosdemexico.com

  93. Pingback: NPM Will Make it Harder to Unpublish Code After Left-Pad Fiasco - Wintellect DevCenterWintellect DevCenter

  94. Orv

    Several years back, a major security hole was discovered in the zlib compression code. Now, for the reasons the author notes, a lot of projects over the years had simply cut-and-pasted the zlib code. That made things nice and simple…until suddenly it was urgent to fix problems with that code. Now dozens of projects had to fix their own private zlib implementations, and I had to track down updates for them, instead of simply updating a shared zlib library and being done with it.

    When you make your own copy of an implementation, you’re basically forking it. You have to maintain it, keep track of security issues, etc. It’s a non-trivial amount of ongoing maintenance.

    Reply
  95. Pingback: On the left-pad drama – ngeor.net

  96. Pingback: npm, PE, and me | Naga

  97. Pingback: Interesting Stuff – Volume VII | Krzysztof Góralski

  98. Pingback: Podcast Episode 41 – Show Update and the Module Dependency Fiasco

  99. Yahav

    So true. Programmers these days will use package or library for everything. Instead of:

    var x = y + 1;

    They will download whole JS library and have:

    var x = MyFancyLib.Math.Add(y, 1);

    Why? Because it’s “fancy”. It is “cool”. Newbie programmers will see this and go “Wow, he is GOOD!” and then guess what? Do the same.

    Reply
  100. Pingback: NPM y left-pad: ¿Nos hemos olvidado de cómo programar? [Eng]

  101. Pingback: Hey, I’ve got an opinion about the NPM / kik debacle too! – The Useless Dev blog

  102. Pingback: 一个名字引发的血案: left-pad 和 npm 的那些事 | 追逐自由

  103. Pingback: Les liens de la semaine – Édition #177 | French Coding

  104. Pingback: left-pad exposed the real problems | Blog Fiasco

  105. Pingback: That Time the Internet Broke - Jay Hoffmann

  106. Pingback: Building a Resilient Continuous Deployment System | Shamasis Bhattacharya

  107. Pingback: How to find the best code on Github | ghonemi

  108. Pingback: Tweet by Tweet 2.1 | Andrew J

  109. Yuriy

    Actually, I totally agree with you with one minor difference:

    It’s not that JS developers forgot how to program, it’s because majority of JS developers didn’t know how to program.

    Let me elaborate on why IMO majority of JS developers didn’t know how to program:
    1. JS from the start as a language was meant for very low-level developers with very low entry level. For most of JS developers it is and was first language to start from and for many of them it’s the only language they know. That’s why no matter how proficient JS developer is (and there are very proficient ones), they were and are forced to produce libraries that even very low level developers would understand and could use, even if this library doesn’t follow common modularisation principles or separation of concerns.

    2. JS was never meant for modularisation – it was created to be included / injected into HTML with global scope variables without any namespaces / packages / modules. And the reason for this was item 1 above – because if there are namespaces / packages / modules, it would complicate language and prevent entry level developers to use JS. So JS from the start was contradicting basic property of structured programming languages – modularity. This was overcome with packing things into local variables inside objects which served and serve as modules, however whole JS community started using it in approx. 2006 i.e. 10 years after initial JS release which again proves item 1.

    That’s why whole JS community does what’s more simpler in the first place and usually doesn’t care if it’s right or not. And even prosperous JS developers couldn’t resist that and try to “moderate” whole community to use right libraries and right modularisation principles. That’s why I would say that JS is doomed to some extent because it has no entry level requirements to be used.

    Personally I wrote algorithms like leftpad in 9th grade in flowcharts and in Pascal as a homework and I clearly understood that this is not something to be released for general public by me, because such libraries existed in Pascal for years written by more experienced developers during the first years when Pascal came out. Then I switched to C++ and found out that 99% of needed functions are already present in libraries like STD, written and tested long ago by more experienced developers. So while I was implementing sorting algorithms on lists by myself as a homework and practice, I would never ever thought of releasing it to public.

    The fact that such libraries are released and used by the public confirms once again that JS community is still very immature in it’s majority and is by no means suited for writing big applications.

    Reply
  110. Pingback: We did not forget how to code | Ouarzy's Blog

  111. Pingback: Depending on dependencies - Redwire Software

  112. Pingback: LeftPad And Go: Can Tooling Help? | 神刀安全网

  113. NoJS

    The IT industry is notorious for not knowing the history of computers and programming. JavaScript Developers more than most. It’s not that they have forgotten, they have never known. Their “new ways” of doing things are usually decades old and full of known problems. Thankfully few of their applications deal with real life things outside of social. Can they learn? Issues like these will tell the tale.

    Reply
  114. Pingback: Realiza programación saludable | el.abismo = de[null]

  115. James

    My C/C++ instructor said don’t re-invent the wheel. I don’t. Before I code any # lines of code I always check to see if someone else had somewhere else. If I spent X hours writing every 10 line function that someone else had written my projects would never make deadlines. It is absolutely absurd to think that someone can’t program because they don’t write an 11 line function but instead include it from somewhere else. I don’t care what language it’s in.

    Reply
  116. Pingback: 4월 1주차 해커뉴스 소식 – devpools

  117. Pingback: How One Coder Almost Broke The Internet By Deleting A Few Lines Of Code – Breaking News

  118. Pingback: NPM 与 left-pad 事件:我们是不是早已忘记该如何好好地编程? | 神刀安全网

  119. Pingback: Risk of dependency | JW's Blog

  120. Pingback: Development Donderdagen #2 – houstonwehaveabug

  121. Pingback: ★ Confiance et certification |

  122. Pingback: How One Coder Almost Broke The Internet By Deleting A Few Lines Of Code - Gerald Pilcher Thoughts

  123. Pingback: Cerrando la semana (V) | sergio.blog

  124. Pingback: How One Coder Almost Broke The Internet By Deleting A Few Lines Of Code | J Walsh Mobile Marketing Agency

  125. Pingback: Don't Fear the Auto-Update | briancoords.com

  126. Eric S

    The underlying problem is that programmers do no know how to program, but that most programmers do not understand complexity very well, and are not good at evaluating whether a solution adds more complexity than the problem is solves.

    Reply
  127. Eric S

    Ack…that should have been “The underlying problem is not that programmers do not know how to program…”

    Reply
  128. Pingback: Don't Fear the Auto-Update - Stay on Top of WordPress | briancoords.com

  129. AntC

    So of the 250+ comments to date,
    one has drawn attention to a serious bug.
    that and one other has noted serious inefficiency in the algorithm.
    There is I believe a candidate ‘padStart’ awaiting ECMA approval
    which appears to have much the same functionality,
    and appears to have noticed that bug – going by its documentation.

    leftpad appears to have no documentation of any worth.

    All that high-flown language in the other posts!
    Might be a good idea to get the software quality right first?

    I’m all for not re-inventing the wheel. Those who’ve used leftpad
    seem to be depending on a square wheel.

    Reply
  130. Pingback: The Ballad of Leftpad: Or, Batteries Not Included | The Poetry of Computer Science

  131. Pingback: Coding Apocalypse – Internet Marketing Wealth Strategies

  132. Pingback: NPM Nonsense and Open Source Grumbling – WorthyD's Blog

  133. MGH

    I’m interested in the 250+ comments (using the post before this one rather than determining it for myself) where only the last has mentioned documentation of modules. I may be old-school, but I’m used to APIs that actually tell you what you need to know to use the API. I don’t have much knowledge of modules and none of npm, but my experience so far is that module documentation usually consists of little more than “here is my module that I wrote, use it and it will save you lots of time!” But then I have to spend time figuring out how to use it, what happens in edge cases, whether it is better than the oodles of other modules that do the same thing, most of which involves reading the code. I spend more effort solving what happens when things don’t go as expected than when they do, and this is very difficult when I don’t know what the module I’m using does. I guess most developers are only interested in making things work most of the time, programming using examples and trial-and-error, which is probably why most software these days is so poor.

    The other thing I’m surprised about is that nobody has mentioned “JavaScript – The Definitive Guide” that tells you everything you need to know about the language. Or that JavaScript is a powerful, but misunderstood, language with prototypal inheritance. It is no wonder that many developers “do not know how to program” in JS.

    Reply
  134. Pingback: ★ Simplicité par défaut |

  135. Pingback: Right Pad ,Left Pad and Both pad的java实现 – dogduck.co

  136. Pingback: How One Coder Almost Broke The Internet By Deleting A Few Lines Of Code « Matt Media

  137. Pingback: Render Conference 2016 sessions – IS Applications Development Services

  138. Pingback: Can You Hack Me Now? | TechSNAP 259 | Jupiter Broadcasting

  139. Pingback: When programmers get weird: The funniest code projects on GitHub — Quartz

  140. Pingback: When programmers get weird: The funniest code projects on GitHub | Cool Stuff Funny Pictures & Other Things

    1. me

      @foobar
      Because that isn’t what left-pad does (it would be str = n>str.length?Array(n-str.length).join(ch)+str:str I believe). left-pad does have a reason for existing: JS’s complete shit standard library makes simple things like left-padding a pain, it’s just that there shouldn’t be a package called left-pad, there should be a package called unshitify.js, or people could just spend a minute or two making a left pad function when they need one instead of relying on such a tiny package by an author who they don’t trust on a website they don’t control always existing.

      Reply
  141. Pingback: Simple Code Is Beautiful – Cloud Up2date

  142. Joachim

    Am I the only one who is more upset that the implementation of isArray is broken than the fact that there is a package for it? It wrongly classifies the string “[object Array]” as an array.

    Reply
  143. Whocares

    Nope. JavaScript “developers” never learned how to program in the first place. They should learn a real language, then maybe the adults will start to take them seriously (at entry level of course).

    But until the millennials finally face reality, these ugly lessons are going to continue to be taught, for anyone who wants to learn from them.

    Reply
  144. K.

    const leftPad = (string, length, padWith) => ((padWith === undefined ? ` ` : padWith).toString().repeat(length) + string).substr(-length);
    // CC0; developed by one-liner K.(wlzla000@naver.com)

    Reply
    1. K.

      const leftPad = (string, length, padWith) => ((padWith === undefined ? ‘ ‘ : padWith).toString().repeat(length – string.toString().length) + string);

      // This works too!

      Reply
  145. Pingback: Publishing a JavaScript Library – for Dummies – Protyposis

  146. Pingback: The Benefits of Coding Offline: On Encapsulated Codebases and Headspaces – Technology Up2date

  147. Pingback: Tool xịn cho dev: Carbide Alpha đã dùng được, nhưng còn hơi “khùng” – buitatthien

  148. Hugo St-Onge

    I’d be curious to run some tests with:
    A. Just a bunch of code doing a bunch of manually coded arithmetics computations;
    B. The same code with all manually coded parts replaced with these insane micro-modules.

    I’m pretty sure performance will be slower and RAM usage higher in B. And for no good reason.

    Reply
  149. Jan

    About your question in the heading, not everyone has forgotten how to program, the trouble is elsewhere. Young programmers are forced to accomplish task easily with minimum of own code present. A junior I taught to program has become kind of assembler. The goal is to find everything you need as an dependency and assemble it together.

    You don’t here in the company: too big overhead! whole package for simple function? are you crazy?
    Right now: don’t reinvent the wheel, assemble the parts together, we have sufficient bandwidth and space.

    And the domino effect, it’s dependency of another library; I will use it too. It’s there anyway, and it will remain there, even after the dependency in question is no longer necessary.

    It’s all about money, producing nice and tiny code is no longer the target. Most of your colleagues don’t anayway and would not appreciate it. They’re no longer programmers…

    Reply
  150. joe

    if you have a myriad of micro packages the developer needs a larger vocabulary of package names. this is why namespacing took over in the Microsoft world, java, php etc.

    trig.sin
    trig.cos
    trig.tan

    requires you to remember trig only. once at trig, you follow your nose.

    the low average age of the npm world blinds it to the long term maintenance debt being built up.

    Reply
  151. Pingback: Kada izmišljati 'toplu vodu', a kada koristiti tuđa rješenja?

  152. Pingback: How One Coder Almost Transgressed The Internet By Deleting A Few Lines Of Code |

  153. Pingback: Retour sur le forum PHP 2016 - 100% web par Kaliop

Leave a Reply

Your email address will not be published. Required fields are marked *