Show HN: SuperUtilsPlus – A Modern Alternative to Lodash
github.com91 points by dhax_or 10 months ago
91 points by dhax_or 10 months ago
Hey HN!
After years of wrestling with Lodash's quirks and bundle size issues, I decided to build something better. SuperUtilsPlus is my attempt at creating the utility library I wish existed.
What makes it different?
TypeScript-first approach: Unlike Lodash's retrofitted types, I built this from the ground up with TypeScript. The type inference actually works the way you'd expect it to.
Sensible defaults: Some of Lodash's decisions always bugged me. Like isObject([]) returning true - arrays aren't objects in my mental model. Or isNumber(NaN) being true when NaN literally stands for "Not a Number". I fixed these footguns.
Modern JavaScript: Built for ES2020+ with proper ESM support. No more weird CommonJS/ESM dance. Actually tree-shakable: You can import from specific modules (super-utils/array, super-utils/object) for optimal bundling. Your users will thank you.
The best parts IMO:
compactNil() - removes only null/undefined, leaves falsy values like 0 and false alone
differenceDeep() - array difference with deep equality (surprisingly useful)
Better random utilities with randomUUID() and randomString()
debounce() that actually works how you expect with proper leading/trailing options
Also genuinely curious - what are your biggest pain points with utility libraries? Did I miss any must-have functions?
> Like isObject([]) returning true - arrays aren't objects in my mental model. Correct me if I am wrong, but Array factually are JS objects and "[] instanceof Object" is true. Fair enough if that does not fit your mental model, but I would not use any library that treats facts like opinions. I agree with the author that it’s almost never what you want. But I agree with you that it’s the reality of the platform, ignoring it will cause its own problems. I’d surface the footgun rather than trying to pretend it’s not there: isNonArrayObject and isObjectOrArray, or something like that Absolutely agree. I also hate that empty arrays are true, which is different from other languages. But I agree that it's better to face the reality of the language than create a function that evaluates [] to false. It trains you a bad habitnand some day that will cause you to introduce a bug. > I also hate that empty arrays are true, which is different from other languages I don’t mind that actually! I don’t think I have much use cases for “empty array is semantically different from non-empty”. Usually I find null/undefined are better choices, an empty array is just a normal array, I don’t expect it to be handled differently What do you think about empty strings being falsy in most languages including js? Null/undefined is a better choice, but there's many occasions where you do not have the power of choice. For example with document.querySelectorAll, which returns an empty array if nothing is found. The simple thing to do is to just check for it's length or just iterate over it's nodes, but still. I prefer empty arrays being falsy. Just to clarify, I'm not saying one is better than the other. I just prefer how it works in other languages like Python. But I still would rather work with the JS language properties, than import a library that changes how I test for empty arrays. > What do you think about empty strings being falsy in most languages including js? I don’t love it! I think it’s inconsistent with empty arrays being truthy. In practice, I see a lot more mishandling of empty strings than empty arrays (eg “!myvar” catching null and empty strings when it’s not what was meant) which hints that it’s not the right thing to do: an empty string is a valid string, whether its semantically different from non-empty entirely depends on the context and shouldn’t be baked into the langage. Generally, I think implicit casts are not a great idea and I’d rather they didn’t exist (one of the few things I think Go got right). > For example with document.querySelectorAll, which returns an empty array if nothing is found Yes I think it’s doing the right thing. It’s indeed returning the list of elements, whether there’s 0 elements or more it’s still a valid list. As you say, you don’t usually need to handle it any differently from a non-empty array (just iterate), so I don’t think it should cast to a different value. However if for example you were passing something like a whitelist as an argument, I’d expect [] to mean “there is a whitelist, allow only these items (ie allow nothing)” and null to mean “no whitelist, everything allowed”. These two things are semantically different, I think it makes sense to cast to different values. I do see your point and it’s definitely at least partly a matter of taste. Again id rather there was no implicit conversion at all, removing the risk of mishandling altogether! Akshually, implicitly casting any non Boolean type to true or false is no better than implicitly casting “0” to 0. :) B-) No better based on what criteria? In what language? This is typical in Python and done even by core-devs. It is how the language was designed and it was designed to support that. In the "akshually" sense. "Zen of programming" (or "I'm smart because I use the word monoid unironically"). "If is an anti pattern", "null values are an anti pattern", "`string' is an anti-type", "util libraries are an anti pattern", etc. And of course "boolean is an anti type" but let's not get into that. :D (Nor into the value of "idiomatic python" as an argument on healthy programming habits....)
7bit - 10 months ago
williamdclt - 10 months ago
7bit - 10 months ago
williamdclt - 10 months ago
7bit - 10 months ago
williamdclt - 10 months ago
nothrabannosir - 10 months ago
7bit - 10 months ago
nothrabannosir - 10 months ago