top | item 35056136

No Lodash

121 points| synergy20 | 3 years ago |thescottyjam.github.io

152 comments

order
[+] phailhaus|3 years ago|reply
I mean...sure? But this isn't very compelling when:

1. Many of these examples are just implementing the function (e.g., _.chunk). Yes, Lodash is written in Javascript, so yes, you can implement them yourself if you wanted.

2. Lodash is tree-shakeable, so if you import the functions you use directly, only those will be included in your JS bundle.

Just use Lodash, it's better than having to maintain your own hodgepodge of poorly documented and tested utility functions.

[+] toastercat|3 years ago|reply
> 2. Lodash is tree-shakeable, so if you import the functions you use directly, only those will be included in your JS bundle.

I don't use Lodash, but recently began work on a project that does. I was surprised (along with the rest of the team) to find out that Lodash is not tree-shakeable by default. So if you do `import { debounce } from 'lodash';`, you're actually including the entirety of lodash in your bundle. More info here: https://lodash.com/per-method-packages

The recommended solution by the lodash team is to use `babel-plugin-lodash` (including a babel plugin to use less code? no thanks) or import the single modules directly like `import throttle from 'lodash/throttle';`. In the end, since we only used about 3 functions from lodash that were trivial to replicate, we just ditched lodash.

EDIT: There is also a `lodash-es` package with native ESM modules which may solve this issue for some. We avoided this also because it had implications with our toolchain.

[+] afavour|3 years ago|reply
Maybe a better writeup would be "the Lodash functions you don't need to bother with any more". Like _.fill, which this article correctly states can just be replaced with Array.fill these days. But e.g. _.zip still has no equivalent.

It would actually be cool if lodash started deprecating functions like _.fill (via semver so nothing breaks, of course) someday.

[+] olalonde|3 years ago|reply
The thing is that the JavaScript version is often more readable than the lodash one (unless you have a lot of experience with lodash of course).

For example:

    _.compact(array)
vs

    array.filter(value => !!value);
Most JavaScript programmers will immediately know what `array.filter(value => !!value)` does but many will have to lookup the lodash documentation to understand what `_.compact(array)` does.
[+] joshstrange|3 years ago|reply
There are 2 big categories for lodash functions:

1. Functions that have equivalently terse native versions (fill, map, etc)

2. Function that have multi-line equivalents (chunk, zip, etc)

Yes you can _.map an object and you can't myObject.map but I prefer Object.[keys/values](myObject).map(...) but for something like _.chunk I absolutely prefer to use lodash. Maybe one day we will see a new major version of lodash that deprecates all the near-native versions of functions so you can still use them but your editors will do a strikethrough and the JSDoc for the function can steer you to the native version but there are still a lot of useful lodash functions.

[+] jonahx|3 years ago|reply
> Lodash is tree-shakeable... > Just use Lodash, it's better than having to maintain your own hodgepodge of poorly documented and tested utility functions.

There are good reasons not to:

- You don't want to add a build step to your project

- You don't want to introduce any additional knowledge burden on contributors to your code, other than knowing JS. Your "chunk" is the few lines of source code in your repo -- not an external thing with documentation you have to lookup.

- You don't want to deal with the security issues every dependency introduces

Let's specifically address this claim, which is often used in roll-your-own vs use-a-library debates:

> to maintain your own hodgepodge of poorly documented and tested utility functions

I feel, in this particular case, this argument is a straw man. The functions in question are basically 1-liners. The likelihood of bugs are low. The need for documentation is nil: the implementations self-document.

[+] itslennysfault|3 years ago|reply
I honestly haven't needed lodash in years. So much is built into JS now or very trivial to do. If I want to diff an array I don't create a diff function. I just diff it. Then there are things like fill, flatten, drop, etc, which are really just part of JS now.
[+] haswell|3 years ago|reply
TFA does not claim that you shouldn't use Lodash (the HN title is incorrect and misleading). It leaves it up to the reader to decide why they might not want to use Lodash and makes no arguments for or against such a stance.

What remains is a pretty useful overview that lets the reader see what each function is doing with emphasis on the how. It is presented as "if you wanna replace this, here's how".

If I'm not already familiar with Lodash and trying to decide whether or not to bring it in as a dependency, and see that all I need is a 1-2 liner in native JS, that's useful information. I might still conclude that Lodash is the right choice, but I think that when examined in the context of the broader industry, where 3rd party libraries are often unnecessary and sometimes actively unhelpful, I think such a page is useful.

Whether or not it's "compelling" will entirely depend on the problem you're currently trying to solve.

[+] philwelch|3 years ago|reply
Introducing a supply chain vulnerability in order to import utility functions that any novice could write is a choice, I suppose. By the way, did you know it’s been seven years since left-pad?
[+] brundolf|3 years ago|reply
Even if you have Lodash in your codebase, there are a bunch of functions it offers that have direct built-in analogues at this point, and I think it's still best to skip the library versions of those

Ironically I don't see all of those in this list. Maybe OP just assumes everyone already knows how not to use those

[+] jagged-chisel|3 years ago|reply
I was expecting more of a 'write your own implementation' kind of thing, but it's not really that.

For example, the replacement for _.concat() is really just advice on how to concatenate arrays in-line. In such cases, I think learning that a packaged function is not needed is pretty nifty.

[+] flippinburgers|3 years ago|reply
This points at a larger problem: the junior developers who gleefully pull in tons of third party requirements which, as far as I can tell, is the supposed "senior" approach in javascript development.
[+] TehShrike|3 years ago|reply
Tree-shaking doesn't help much when the tree-shaken implementation is so bloated.

Here's the one you referenced, lodash.chunk: https://unpkg.com/lodash.chunk – 140 lines after removing comments and whitespace.

That's pretty small compared to a lot of the lodash utilities. Try spot-checking a few on unpkg.

I prefer angus's `just` utilities: https://github.com/angus-c/just

[+] bstar77|3 years ago|reply
If you are using code splitting then importing directly gains you nothing.
[+] jerf|3 years ago|reply
Would be nice to have some indication of the size of the replacement visible before I click, so we can scan down the page and get a sense of what is what.

That is, I'd love to see how many of the replacements look like

    _.now()   ->   Date.now()
and how many of them are like

    _.invert(object) -> 

    function invert(obj) {
      const newObj = {};
      for (const [key, value] of Object.entries(obj)) {
        newObj[value] = key;
      }
      return newObj;
    }
Also clicking through I see a lot of "when lodash was created this was necessary because X, but now we can Y". Kudos for including that. It is both informative and helps this not come off as an attack.
[+] andrewla|3 years ago|reply
Yes -- this seems like it would be significantly more useful if it divided between "vanilla Javascript now supports this or similar functionality natively" vs. "if you're getting rid of lodash and use these functions, then you'll have to write your own variant, along with tests".
[+] Kerrick|3 years ago|reply
> Also clicking through I see a lot of "when lodash was created this was necessary because X, but now we can Y". Kudos for including that. It is both informative and helps this not come off as an attack.

It reminds me of https://youmightnotneedjquery.com/ in a good way.

[+] Rumudiez|3 years ago|reply
Lodash gets so many things wrong I’d rather not see it in most projects. I appreciate a good utility library for JS projects but my go-to choice has to be Ramda[1]. Every function it exports is curried and works great with pipe which enables me to write highly reusable and composable functions in pointfree notation. I have never been as productive with lodash, and I find the functional style easier to read

[1] https://ramdajs.com/

[+] andrewstuart2|3 years ago|reply
Libraries like lodash/underscore don't get popular for no reason. The API matters, and readability matters. Sure, you can do these things without the library, but the readability suffers. Adding in the ability to chain these calls into a nice little readable "paragraph" of small single step data changing functions, there's significant value in the underscore and similar compatible libraries.
[+] afavour|3 years ago|reply
Having worked in the JS ecosystem for far too long now it's enormously satisfying to remove these dependencies. First it was direct DOM manipulation without jQuery getting in the way, now it's direct JS calls without a utility library getting in the way. The ecosystem really has come a long way.

It's also worth noting that lodash lets you import individual functions, e.g.

import throttle from 'lodash/throttle'

so even when you do need a utility function you can avoid pulling the entire library into your code.

[+] stolenmerch|3 years ago|reply
Looks like this will be removed in v5. "For example, throttle uses debounce internally. In a project using both methods from the main lodash package, throttle will import the same debounce module as any code that imports debounce directly, so only one copy of debounce will wind up in a webpack bundle."
[+] CharlesW|3 years ago|reply
> Having worked in the JS ecosystem for far too long now it's enormously satisfying to remove these dependencies.

Assuming you're working on commercial products, how do you decide when to move to new-ish native functions? For example, do you log feature detection for the function a month or two prior to the planned change?

[+] Zetice|3 years ago|reply
There’s an entire category of developer that concerns themselves with stuff like this, and I wonder if they know you can be a successful dev and not care one bit about taking your imports this seriously, and instead just grabbing libraries from npm.

It strikes me as the difference between knowing why your role exists and not realizing you deliver organizational value, over engineering perfection.

[+] whstl|3 years ago|reply
An important role of developers is knowing which tools exist and what can be used to provide value.

To use Lodash, a developer needs to know what is available there in the first place. You're taking it for granted, but everyone, you included, had to study its documentation and memorize which functions were there, even if it was only to "look it up" later.

Someone like you could have said a few years ago about Lodash: "why do I need this stupid library, I will just use for loops everywhere, like I learned in college. They get the job done and my role is to provide value, not to care about libraries or code reusability".

With this website, it's the same thing: it's there to teach you which things in Lodash aren't needed anymore and which are. Then it is up to the developer to use what's best. Not everything in the internet is prescriptive.

Blind dogmatism shouldn't have a place in our profession.

[+] HeavyFeather|3 years ago|reply
Speed brings value. Loading dash without optimizing it carries a huge weight. Weight can slow down users. Users leave the cart before completing a purchase.

Lodash is engineered to deliver “perfection” and performance, to an absolute fault. Try `import {unary} from 'lodash'` and tell me how big the bundle gets. FYI unary should be `fn => x => fn(x)`.

On the other hand, copy-pasting actually-useful utilities like groupBy from some random site defeats the purpose of npm. Luckily there are sane Lodash alternatives like Just:

https://github.com/angus-c/just

[+] forgetfulness|3 years ago|reply
Considering that a bigger engineering and social problem in the Javascript world is the plague of micromodules of dubious provenance, arguing against using solid and trustworthy utility libraries is counterproductive, or even symptomatic.

Using libraries like lodash, instead of adding 12 left-pads of different authors to the dependencies manifest, is an improvement over the status quo.

[+] usea|3 years ago|reply
You can be a successful dev without doing a good job. Many people just want to do a good job and don't particularly care about being "successful."

It's not that your coworkers don't know you can get away with doing a bad job, it's that they're not motivated by the same things that you are.

It's true that in some contexts, throwing npm libraries at the wall to see what sticks is delivering organizational value. In many others, it's negative value.

[+] boredtofears|3 years ago|reply
this attitude is how you get average client payload size measured in the tens of megabytes
[+] lake-view|3 years ago|reply
Missed a golden opportunity to call this Nodash.
[+] ch4s3|3 years ago|reply
I would have gone with em dash, since lodash was a successor to underscore, so this would bring it back in a typographic direction.
[+] xlii|3 years ago|reply
I’d still use Lodash functions over the native ones for chaining [1].

I like Elixir pipelines so this is equivalent. I suppose it depends on preference if someone chain or not.

[1]: https://docs-lodash.com/v4/chain/

[+] moomoo11|3 years ago|reply
To be fair a lot of these utility functions are easy to implement without the dependency.

And one can install only the individual lodash functionality that’s required. Personally I’d do this in the node/js ecosystem because everyone does it and why not? It’s battle tested.

I work primarily in Go so I’m used to writing my own utilities for many things. It isn’t that complicated and end of the day it’s just basic programming.

[+] feoren|3 years ago|reply
> Personally I’d do this in the node/js ecosystem because everyone does it and why not? It’s battle tested.

When almost all software is completely terrible, "everyone does it" is not a compelling reason to do anything. And this approach is indeed battle tested, in battles that were abject massacres (see left-pad).

[+] strict9|3 years ago|reply
lodash and other utility libraries can be helpful when backend devs who don't usually work in JS need to do something complicated on the front end.

That said, if focusing on front end dev work I think it removes knowledge of underlying apis which can be counterproductive in the long run. If you have enough knowledge to achieve in plain JS what is done with lodash, you are better set up for success when given a problem not yet solved in your code base or stackoverflow.

[+] motogpjimbo|3 years ago|reply
This is true for backend frameworks too. In the PHP world, Laravel contains many helper functions that uselessly duplicate functionality already available in the standard library. Not only is this a waste of effort from the framework's author, it also unhelpfully silos some developers into Laravel-specific knowledge. I had a colleague who had worked professionally as a Laravel developer for several years but then failed a job interview because he'd literally never written a vanilla PHP script and had no idea how to go about it.
[+] haswell|3 years ago|reply
The title needs an update. The current title is actively misleading and is affecting the comments.

The content does not claim that you should not use Lodash. It only presents alternatives to Lodash functions. The actual title "Lodash Replacements" is far more accurate by reflecting what the page contains, and doesn't invite misinterpretations or ideological responses.

[+] QuelqueChose|3 years ago|reply
Am I misreading or are there no translations to pure JS available specifically for collections? The ease of being able to do "what i think I want to do in my head" with a collection using a one-liner often is the primary reason I'd use anything Lodash-y in the first place. The fact that I can import those methods directly to my projects and forget about the guilt of bundling the rest of the library really have kept Lodash top of mind for me for years.

I have found that not so much when writing my own projects and tinkering, but specifically for "real" work (at my job) is when I have to deal with iterating over collections all the time. Anything less readable than Lodash is just overly annoying thanks to JS verbosity. Most people wouldn't remember to pull these methods out of a utils directory that we maintain simply for the purpose of ignoring packages like Lodash.

By a collection, I'm talking about an array of objects that follow the same pattern.

[+] atsjie|3 years ago|reply
I agree, the days of chaining lodash functions together are pretty much behind us.

But I still like lodash, particularly for functions like these:

- words

- kebabCase / startCase / snakeCase

- partition

- debounce

Basically the more advanced functions for which no readily available alternative exists?

[+] toastal|3 years ago|reply
> You need to enable JavaScript to run this app.

What app? Is this an app? If it is, why didn’t you name it or tell me what I’m missing out on instead of using the default some framework spits out.

[temporarily enables JS for the site]

Oh, it’s just static informational content that should have good SEO and TUI-compatibilty but missed the mark. Don’t need Lodash? How about this page doesn’t need JavaScript! These code examples are the perfect semantic use case for the <details> + <summary> elements.

(And I love JavaScript, but for contexts that need it like applications)

[+] hot_gril|3 years ago|reply
If someone on my team imports Lodash and uses it all over the place to significantly reduce our LoC, fine by me. What makes it annoying is when someone adds that whole dep just to use it once, or for something ES6 already has (e.g. map). Same with Axios instead of fetch.
[+] moogly|3 years ago|reply
Didn't see anyone mentioning Lodash's IMO biggest flaw: being null/undefined safe. As in `_.map(undefined, (item) => item)` returning an empty array. Promotes sloppy code and interfaces really badly with TypeScript.
[+] iKlsR|3 years ago|reply
Fun exercise, use cgpt or copilot to convert the descriptions into code and then roll your own then check correctness and benchmark cgpt, your own, author's own and lodash.