
Lists of JavaScript methods which you can use natively - tilt
https://github.com/cht8687/You-Dont-Need-Lodash-Underscore
======
EliAndrewC
Alternate title for the article: "Lists of lodash features replaced by ES6 if
you don't mind throwing an exception when given invalid input such as null or
undefined".

All kidding aside, a lot of our lodash code ends up looking something like
this:

    
    
        function (xs) {
            return _(xs).pluck('foo').filter().value();
        }
    

That code clearly expects that xs is an array of objects. However, we might
occasionally end up with xs being undefined, or with xs being an array but one
of the elements is null, etc.

Most of the time, we want our function to just swallow those errors and return
an empty array in such cases. This is exactly what lodash does, but if we
tried to call xs.map(...) in that case we'd get an error. Similar caveats
apply for grabbing the foo attribute if one of the array elements ends up
being null or something.

For this reason, I recommend continuing to use lodash almost all of the time,
even when there's a native Javascript method available.

~~~
sly010
> if you don't mind throwing an exception when given invalid input such as
> null or undefined

That's exactly what I would expect. If only everyone always thrown an
exception on any undefined, life would be so much better.

~~~
madeofpalk
Depending on the particular domain of the task.

There are perfectly valid reasons why silently failing is OK.

~~~
squeaky-clean
Seriously. A really common example, ever have a website that completely fails
to load when you're running adblock? Would you rather have a blank page, or a
99% functional website with a couple of error messages in the console?

~~~
jnbiche
The answer is: that's an expected failure, so you make the error handling
explicit by catching the error and taking care of it appropriately (including
proceeding to the rest of the page load, naturally). Implicitly handling
errors behind JavaScript's loose typing rules is a recipe for disaster.

~~~
barrkel
Explicitly handling errors is almost always a bad idea, no matter what
programming language it is. There are very few errors you can reasonably
handle, and they must be designed for. It's specific application domains that
need different handling strategies: e.g. embedded, device drivers, software
that's trying to maintain some very strict invariants. A web page isn't
usually one of them.

Usually errors should be sent up the stack to the request / event loop and
logged / telemetry / etc.

The question here is something different, though. It's what should be
considered an error, vs what should use the null object pattern. I don't think
anyone can make a categorical judgement on which is better without context.
It's suggested here that the null object pattern implemented by lodash is
desired; I don't think it's wrong in principle to rely on it, as part of a
cohesive design - e.g. it's used in such a way that it doesn't make
development or finding bugs harder than necessary.

~~~
klibertp
Take a look at Common Lisp and Dylan and their respective condition/restart
systems. This is how error handling _should_ look like: they let you handle
your errors where it makes sense and naturally recover from them if it's
possible.

------
klibertp
The need for Lodash and Underscore is diminishing, but not because of JS
getting native support for a subset of utilities, but because there are
already better alternatives. Utility libraries like Ramda[1] or pointfree-
fantasy[2] with related modules which offer a better support for FP idioms and
more useful higher-order functions are what made me drop Underscore.

I think that, with a language with such tiny stdlib, there always be a need
for some kind of utility belt-style library ("if only for convenience", as
another commenter write, which is actually the main point of such libraries).
It's just a matter of choosing the best library for your coding style and
project at hand. It may be a hassle, but an alternative is an stdlib the size
of Python's - and I'm not sure if it's a good direction.

[1]
[http://ramdajs.com/0.21.0/index.html](http://ramdajs.com/0.21.0/index.html)
[2] [https://github.com/DrBoolean/pointfree-
fantasy](https://github.com/DrBoolean/pointfree-fantasy)

~~~
skrebbel
The Ramda API changes with every version. If you don't pay attention for a few
months and accidentally upgrade (Ramda doesn't seem to want to do Semver, I'm
not sure why), then suddenly half your code is broken.

We depend heavily on Ramda and I like its API better than Lodash and friends
(it's more guessable, more consistent), but with the changes it keeps having I
regret choosing it.

Our core product is currently on a Ramda version that's so old that there's no
online documentation published for it, so we just look in the source. We ought
to upgrade but I'm not convinced all code paths that use R are sufficiently
covered by automated tests.

~~~
ascagnel_
Technically, Ramda is using semver; 0.x releases are used for when the API is
still changing substantially[0].

[0] [http://semver.org/#spec-item-4](http://semver.org/#spec-item-4)

~~~
skrebbel
Ahyes, good point. In the Ramda authors' defense, they never claimed it to be
good for anything production level.

------
have_faith
Instead of searching for the compatibility of each individual function I would
much rather just use a custom build of Lodash with the collection of functions
I need (which can even be handled by your build process now and some tree
shaking). And I get a lot of utility functions with it too that I use a lot
like Throttle and Debounce.

~~~
xiaoma
If you just use lodash from a CDN, many, many users will already have it. If
you make a custom build, then everyone has to download.

~~~
Klathmon
Didn't someone do a study and found that cache hit rates for CDNs were in the
10-20% range?

You might be better off bundling lodash and tree shaking everything you don't
actually use away.

~~~
majewsky
And it will also lead to the site not working out-of-the-box for privacy-
conscious people like me who block third-party JS by default.

~~~
Klathmon
Well you can avoid that with an inline script that checks for it and includes
it from a local path if it fails.

But that's just more waiting, and you still end up downloading the ENTIRE
script (unless you get REALLY fancy with webpack in a way I don't even want to
think about...)

~~~
girvo
> But that's just more waiting, and you still end up downloading the ENTIRE
> script (unless you get REALLY fancy with webpack in a way I don't even want
> to think about...)

I have a friend who has done, in production, exactly what your subconscious is
afraid of. I should get him to do a write up sometime: it's both amazing and
horrifying at the same time...

~~~
Klathmon
I'd actually love to see that!

I've thought about it a bit before, and always ignored it because there'd be
no real benefit.

But i could see writing a crazy webpack config that breaks out all my lodash
functions into their own bundle, then tries to add a script tag to the CDN
version, doing some quick processing to determine if it's in the cache, and if
it's not falling back to including my own custom-built script tag (and
canceling the request to the CDN version).

I'm sure it wouldn't provide any benefit to anyone, but it would be a fun
code-golf exercise!

------
frostik
There's a huge gotcha: _.map, _.forech, ... can iterate over objects (often
used as associative arrays) - Native map can't.

At some point you'll need lodash and co again - at least for convinience.

~~~
DrJokepu
Object.keys() is rather well supported these days though.

~~~
frostik
Yes, but means that you need to implement map, foreach, filter yourself. So
you might be better off with lodash.

~~~
mullsork
I think he's referring to `Object.keys(object).reduce`. We polyfill
`Object.entries` so we do `Object.entries(object).reduce((result, [key,
value]) => ...)`

------
onion2k
[https://github.com/cht8687/You-Dont-Need-Lodash-
Underscore#_...](https://github.com/cht8687/You-Dont-Need-Lodash-
Underscore#_find) \- the Array.prototype.find() method that's suggested has
_no_ support on Android's stock browser or Chrome for Android. That's a _huge_
chunk of the browser market, but there's no mention of it on the list. In
fact, there's no consideration for mobile at all on any of the suggestions.

If you're going to use any of the suggestions, check MDN or CanIUse first.

~~~
lloyd-christmas
Here's another useful resource, I think I found it from HN a while ago.

[http://kangax.github.io/compat-table/es6/](http://kangax.github.io/compat-
table/es6/)

------
hkjgkjy
I understand why, and once upon a time I was the guy who would commit code
where I replaced jQuery and underscore (at the time) calls with native calls.
It works, and is totally fine. But what was the point? Some kind of
optimization? It was pretty pointless in hindsight and just made my coworkers
trouble. Now all my JS code is Ramda/lodash all the way, and it's great
(although I opt for Clojure/script when possible)

~~~
dpweb
These emperor has no clothes posts are very popular, and some may ask what's
the point. It's a question worth considering. I think by instinct people
especially programmer/engineer types like the idea of purity.

But if you consider that every decision must be put through a cost/benefit
analysis, I think the appeal is that - I (or anyone in the future that will
ever touch the code) must learn JS. OK. Now they must also learn framework X.
That's the added cost.

Our memory is limited too, like a computer chip. When I know JS I can
instantly access what I need. If you think of a Google or cheat sheet lookup
like a disk access, well memory is faster than disk.

~~~
_asummers
My rationale is that any one of these functions is probably going to be put
into a utility function that's documented and named already, and of course
tested with some optimizations, in some file somewhere in my code base. If
it's useful enough, it'll probably be there. And while I don't often do front
end, having these utilities support older versions of browsers or if there
exist quirks in certain versions of browsers that render the solution
nonviable is just not something I want to spend time caring about. When I did
Java, the same articles would come out about Guava and Apache Commons.

One should not be afraid to use battle tested libraries, but don't bring
dependencies for no reason.

------
mduerksen
_.filter is NOT equivalent to Array.prototype.filter.

The array could be null/undefined, in which case the _.filter just works fine,
but Array.protoype.filter does not.

I hate to riddle my code with null checks I actually do not care about.

~~~
eknkc
(arr || []).filter... Is something I do when I'm not sure if the array is null
or not. Looks shitty but works fine. (Now if arr is not falsy and not an array
either, this blows up. But I don't know what lodash does then too)

To be honest, I'd rather check / handle nulls rather than to rely on an
external library semantics. They might also change it tomorrow and upgrading
would be a pain.

~~~
jdd
The language changes too. In ES5 `Object.keys` throws an error for
`Object.keys('abc')` but in ES6 it returns an array.

~~~
eknkc
Still a pretty conservative breaking change. Something you'd expect from a
committee of people. Lodash has more wiggle room to make absurd changes in
future.

~~~
jdd
Lodash follows semver so major changes are opt-in unlike lang level ones
though.

------
jacobr
My main concern with Lodash is not necessarily the size, but that it adds to
the API surface a new developer has to learn when entering a project. You get
a lot more value from the cost of learning a dozen API methods from React
compared to having a developer looking up pluck, pull, xor, zip, flow, etc
from lodash.

I really recommend "Sebastian Markbage: Minimal API Surface Area - Learning
patterns instead of frameworks" [http://2014.jsconf.eu/speakers/sebastian-
markbage-minimal-ap...](http://2014.jsconf.eu/speakers/sebastian-markbage-
minimal-api-surface-area-learning-patterns-instead-of-frameworks.html)

------
seanwilson
For the sake of 25KB for the full Lodash library, is it really going to make
much difference? That size will be eclipsed by just a single small image on
your website.

Development is all about tradeoffs. Liberal use of Lodash can make for clean
code that abstracts away subtle browser differences. For a small download size
it sounds like a great tradeoff to me.

~~~
spriggan3
If the 25KB are packaged with each library you add to your webpage, + ads , +
analytics then maybe.

One often doesn't need lodash. In fact, the only methods one does need are
Object.keys to get the keys of an object and Array.prototype.reduce to iterate
over an array, 90% of the time.

But yes, difference, zip, chunk, assign... are semantic and make for cleaner
code. And yes flatten, xor are non trivial to implement, and the code one
doesn't write is the code one doesn't have to test if already tested.

Of course, the best solution would be for the ECMA spec to implement most of
lodash methods. I would also like to see an official way to curry, the same
way Function.bind allows partial application.

------
SamiTriki
Well, Lodash is focused on performance, and 3.X.X supports IE8 and a lot of
older browsers, it's a pretty solid util library. If you add in all the good
utilities function. As long as you use them a lot in your code, Lodash is
definitely worth it

------
jzig
A nice thing Lodash has that Native doesn't is the 'matches' shorthand for
things like find. I find it easier to read and quicker to write than a
callback.

    
    
        _.find(items, {id: 10});

------
hnskeptik
Functions like repeat() still need lodash - it's not supported on IE and
Opera:

[https://github.com/cht8687/You-Dont-Need-Lodash-
Underscore#_...](https://github.com/cht8687/You-Dont-Need-Lodash-
Underscore#_repeat)

------
erokar
I prefer Ramda to Lodash and Underscore. It has a lot of functions that are
missing in vanilla JS.

~~~
jdd
You might dig

[https://github.com/lodash/lodash/wiki/FP-
Guide](https://github.com/lodash/lodash/wiki/FP-Guide)

------
acbabis
I don't use Lodash, but I remember reading that it does lazy evaluation[1].
For example, if you map an array, then take the last 3 items, it only calls
the map function for those 3 items.

Does anyone know if V8 can do any optimizations like this for native Array
functions? That would be a good thing to know before downloading lodash.

1) [http://filimanjaro.com/blog/2014/introducing-lazy-
evaluation...](http://filimanjaro.com/blog/2014/introducing-lazy-evaluation/)

~~~
spaethnl
This cannot be done with native array functions as they exist now.

The reason Lodash is able to do this is because the collection is wrapped in
an a special object that keeps track of all of the functions you call on it.
Those functions don't run until you call .value() on the whole pipeline that
you have setup, and then the optimization happens.

Note that this requires a separate API. One API returns your results
immediately, the other (lazy) API instead returns a wrapper object after each
call without yet doing the mapping/filtering/etc, ready to add more
instructions to the pipeline that you must ultimately call .value() on in
order to actually run.

Native functions don't have this separate lazy API that does the wrapping with
this special object, and don't have/return an object with a similar .value()
method.

------
moron4hire
Getting rid of unnecessary dependencies can have a huge impact on site
download performance, especially on mobile. Even in the case of having the
site cached, every resource you link will have to perform an HTTP request to
at least receive NOT-MODIFIED. It can add up, especially if you're on a semi-
spotty connection and trigger TCP congestion avoidance.

~~~
Klathmon
Don't miss the forest for the trees. Re-implementing _.forEach, _.map, and
_.reduce to do something like loop over objects yourself is going to most
likely end up taking more code than just using those functions from lodash.

Not to mention that you most likely won't have the same amount of testing,
speed/optimization, or "familiarity" across devs with a home-grown solution.

Yeah, don't pull in lodash if you are making a small library and you only need
it once, but if you avoid lodash in a codebase where you use it a non-trivial
amount, it's most likely going to be worth it.

Plus with modern (at least to js land) tree shaking, and/or the way that
lodash can package each function individually, you don't need ALL of lodash in
order to use one or 2 functions.

~~~
moron4hire
I do not agree at all. What is so hard about for loops? I do not agree that
using the native-to-the-platform looping constructs will create as much code
as half a megabyte. I'm looking at it right now: the full build of Lodash is
503KB. That's also half-a-meg of code that needs to be parsed by the JS
engine. And nothing else you said has anything to do with site performance. Do
users care if it took you 10 seconds versus 11 seconds to write a particular
looping construct? Do clients care?

~~~
Klathmon
Well you conveniently skipped right over the part of my comment where I said
that you shouldn't be using the whole 500kb lodash library... (also, it's
disingenuous at best and borderline lying to say that lodash is 500kb. The
DEVELOPER version is 500kb, the production version is 67kb before gzipping,
and 22kb after gzipping)

If you are only using _.forEach, then you should only include _.forEach, which
comes out to about 10kb before gzip compression, 5kb after (i just built it
myself to test). And all but about 1.2kb of that is "core" code, so if you add
additional lodash functions, most of them will increase the code size by about
2kb at the most.

That means that for an overhead of about 8kb, you can start adding extremely
useful functions all throughout your codebase with very little overhead. 1.2kb
to easily and quickly iterate over an object using the key and the value in
each block;

    
    
        _.forEach(obj, function(value, key) { // do stuff })
    

Pure js:

    
    
        Object.keys(obj).forEach(function(key) { var value = obj[key] // do stuff })
    

Not that much of a difference space wise, but the performance is terrible if
you are iterating over a large object, and by using Object.keys you exclude
some UAs.

Now let's look at _.find in an object...

    
    
        _.find(obj, { 'age': 1}) // returns the first object (in the object) that has a property 'age' that equals 1.
    

Pure JS:

    
    
        var objKeys = Object.keys(obj)
        var retval
        for(var i; i < objKeys.length; i++) {
          var value = obj[objKeys[i]]
          if ('age' in value && value.age === 1) {
            retval = value
            break
          }
        }
    

And that's untested, will only work for an object of objects, has unknown
performance, and sure as shit took me more than 1 extra second to write (about
5 minutes once i looked up what the compatibility of the 'in' operator is).

You could use the native .find() function, but that won't work on chrome for
android, android browser, IE (any version), safari 7 and older, and opera.
Plus you'd still need something like Object.values() in order to convert the
"parent" object into an array to search through.

Plus what if i want to find an object in an array and in another object?
(which I actually just had to do, which is why i thought of this use case)
Well now you've just doubled your code, doubled the amount of tests you need
to write, doubled the chance for random bugs to crop up (what happens if one
of the object values is undefined? What happens if obj is null?).

With stuff like the lodash cli where you can make builds that literally only
contain what you need, the lodash babel plugin that will allow you to require
lodash functions and it will build only what you need, or webpack which will
tree-shake away everything you don't need (and actually does a better job than
the lodash-cli does!), there's no need to avoid lodash like the plague.

I'm not saying include all of it, i'm not saying use it in everything, i'm
saying that you should use your brain and include it if it's going to increase
the speed that you can develop, reduce the number of bugs you will face,
simplify your codebase, and won't negatively impact your users. (after all, a
single image will blow the 5kb of js you'll be saving out of the water)

~~~
moron4hire
I skipped over it because it's a solution in search of a problem.

I think developers should be expected to understand the native constructs of
the language they use. You previously also talked about "being more familiar
to onboarding developers". Why should Lodash be more familiar than the native
looping constructs to anyone? Why _would_ Lodash be more familiar to a
developer you're onboarding who is more used to some other library completely?

If you're not used to using Lodash, then it would not be a time savings to use
it, as you'd have to spend time learning its idioms. It means you've probably
learned other idioms, instead (perhaps, you know, the ones you should have
learned to be able to claim to know how to use the language). So if you know
the native idioms, there isn't a point to learning Lodash.

You had to take time to look up operator-in because you're not used to using
operator-in. Regardless, it was a waste of time. What's wrong with the
following code?

    
    
        for(var k in obj){
           if(obj[k].age === 1){
              // there you go
           }
        }
    

And I mean problems with that code itself, not problems that are actually a
problem with upstream code? And how much of the problems with that upstream
code are because your project is a Gordian Knot of 3rd party dependencies?

You default assume other people's code is better than yours. In the last 20
years of software development, I've seen code better than mine in several
standard libraries. But the JS ecosystem is not one of them.

~~~
Klathmon
>You had to take time to look up operator-in because you're not used to using
operator-in

I'm using in (`if('age' in value)`), but not for..in. There's a difference. I
don't need to use that (you didn't in your example, even though you should
have), but then my code would blow up in many of the same cases as yours will.

Anyway, what's wrong with that code is you'll need a hasOwnProperty check,
you'll need to break out of the loop when done, it blows up if 'age' isn't a
property on one of the objects in the object, it blows up if one of the
properties of obj isn't an object, it blows up if obj is null/undefined, and
it will deoptimize the entire function it's in in most cases in V8.

To at least fix the bugs that yours has that mine didn't, your code should be:

    
    
        for (var key in obj) {
          if (obj.hasOwnProperty(key)) {
            var val = obj[key]
            if ('age' in val && val.age === 1) {
              // there you go
            }
          }
        }
    

but again that still needs some undefined/null guards at a few spots, and it
needs to be able to handle both an array and an obj at where obj is to really
be an equivalent of what i was using _.filter for.

>You default assume other people's code is better than yours.

No, I know the lodash code i'm using is better than mine because i've looked
at it, i've looked at it's test coverage, i've looked at it's performance
numbers, and i've looked at it's usage.

Also... >I skipped over it because it's a solution in search of a problem.

Then why did you skip this part in my last comment:

>it's disingenuous at best and borderline lying to say that lodash is 500kb.
The DEVELOPER version is 500kb, the production version is 67kb before
gzipping, and 22kb after gzipping

You made me curious, so i actually took a look at my current in-development
app i'm writing that i include lodash. The grand total from all lodash
functions is 22k un-gzipped, and 7k gzipped.

For that i've significantly reduced my code complexity, increased
compatibility, reduced the amount of tests i needed to run and maintain, and
improved performance in one pretty out-there edge case.

You don't need to use lodash, and in many cases you shouldn't. But don't act
like your applications are better than others in any way because you aren't
using lodash.

~~~
moron4hire
> it blows up if 'age' isn't a property on one of the objects in the object

No it doesn't. It will return as undefined, which evaluates to false when
compared to 1 using either triple- or double-equals.

And why call hasOwnProperty here? I'm pretty sure I want to know the age of
any properties inherited into my object from a superclass.

At worst, I will grant you an undefined/null check:

    
    
        var val = null;
        for(var k in obj){
          if(obj[k] && obj[k].age === 1){
             val = obj[k];
             break;
          }
        }
    

This works with both objects _and_ arrays.

~~~
jdd
I'm guessing after repeated use you'd abstract that into a function. Maybe
even a collection of them.

~~~
moron4hire
No, why would you? It's just a loop. Not all code deduplication is a good
idea.

~~~
gnaritas
> No, why would you?

Because he's a better programmer than you are, and he knows it.

> It's just a loop.

There are many kinds of common patterns in loops, abstracting them into
resuable higher order functions, aka a collections api is rather basic
functional programming; "it's just a loop" is a blub phrase of someone who
doesn't see the point because they have tried it long enough to understand the
value in a different paradigm.

~~~
moron4hire
I know it's currently thought as so, but functional programming is not the be-
all, end-all paradigm. If you've been around for a while, you'd have seen the
ebb and flow a few times already.

~~~
gnaritas
No one said it was, but in this use case it's far superior to hand written
loops. Virtually all modern programming languages have a functional
collections API precisely because of this advantage. If you're still writing
loops by hand, in nearly all cases, you're stuck in a less effective
procedural programming mindset and have simply stopped updating your skills
beyond the basics.

If you've been around for a while, you should have already accepted the
benefits of functional programming in the places it's most effective and
banished low level procedural programming of loops except in cases where
extreme optimization is required. There's no eb and flow here, higher order
map/reduce/filter style has been the best way since the 60/70/80's when Lisp
and Smalltalk were doing it.

------
worldsayshi
I would consider switching from underscore if there was a reliable polyfill so
that I wouldn't need to be aware of all these browser compatibility
constraints. That way I can just drop the polyfill in a couple of years
instead of replacing every underscore use.

I guess the babel polyfill would do this.

~~~
shados
babel polyfill is roughly core-js.

------
bshimmin
It took me a moment to figure out what this was for:

[https://github.com/cht8687/You-Dont-Need-Lodash-
Underscore/b...](https://github.com/cht8687/You-Dont-Need-Lodash-
Underscore/blob/master/convert/convert.js)

Cripes!

------
fbreduc
This seems like a great post on why you should be using lodash.. especially
all those IE unsupported things. Like mentioned in the comments, it's not just
about having one or two of these features, it's about how they compose so
nicely in lodash

------
the_duke
You'll be stuck with using a shim for old browsers for quite a while to come,
especially when it comes to mobile.

The good thing is, at some point in the future you can just drop the shim and
everything keeps working.

Lodash does has a lot of additional nice utility functions though.

------
emodendroket
Yes, you could implement every feature of just about any library yourself.
Why, though?

~~~
pgl
I think the point of the page is to demonstrate that for many, many lodash
functions, there are direct equivalents in native JS - not rewritten features.

~~~
emodendroket
They don't have the lazily-executed features though, right?

------
piotrkubisa
That's interesting why some of functions (_.repeat, _.findIndex) were marked
as "Not supported" in Opera but all of them are supported in Chromium-based
browsers. Did the author only consider Presto-powered Opera?

------
cel1ne
Would it be possible to build an tool that scans your code for simple helpers
you wrote yourself or that you include from dependencies and replace them with
equivalent functions of lodash or native?

------
spriggan3
That list ignores mobile browsers though, the ones that are mostly never
updated.

------
jlebrech
maybe lodash itself should warn when something is available natively, but for
it to add extract browser detection for this is overkill.

the real way to do this is to write ES6 and compile to ES5 and provide both to
the browser.

------
oblio
What do the checkmarks mean?

------
s369610
waiting for non mutating versions of sort and sortby

~~~
Bahamut

      [].concat(array).sort()

------
rafinha
or you can just use lodash

------
alixaxel
The native version of find is still using _.find.

~~~
RobertKerans
Eh? No it's not, it's just using Array.protoype.find

------
andrewvijay
"However, when you are targeting modern browsers" \- possibly one of the worst
mistakes companies do. Then they decide to support older browsers after
customers complaints. Then shit goes down!

~~~
LoSboccacc
I've yet to see a company going under and citing lack of old browser support
as principal culprit.

------
elmigranto
You might also not need to write any code at all, just set up a form for
customers to send in their requests and hire a bunch of people to manually
process them. Bam! 0K, no dependencies, almost instantly working web service.

But that's not your priority when building website, it doesn't matter if your
JS is 60Kb or 20. No one cares how much dependencies you build system pulls.
You need tested, reliable and working libs to do their job, and not write your
own routines for 3 months.

