For me the "should I use a library for this" comes down to if I want to be able to dip under the abstraction.
For instance: terminal color codes. I'm building for linux, but would like my code to be reasonably portable to other platforms. By inserting my own \033[m... Codes, I take responsibility for doing colors on other platforms too, whereas a dependency absolves me of that.
On the other hand, if I need a graph algorithm like Bellman-Ford, I don't want to reach for a library, because that immediately forces me to use their structs for every graph node. I might also want to tune BF specifically to my graph's shapes, etc.
Interestingly I've only ever ran into this problem (as being a problem) in Advent of Code - you need a certain (more exotic) graph algorithm and you only find an example that goes contrarian to your current model.
At work I don't seem to need these weird algorithms, or they are in the language's standard library/default math or graph package and it's not worth reimplementing anyway.
Except it doesn't. Users don't care if the reason something is broken on their platform is your own code or a dependency.
IME platform abstractions often tend to be a trap because they can only abstract 90% without making compromised whereas if you do it yourself you can pierce the abstraction for the remaining 10% and get the best result on all platforms.
For instance: terminal color codes. I'm building for linux, but would like my code to be reasonably portable to other platforms. By inserting my own \033[m... Codes, I take responsibility for doing colors on other platforms too, whereas a dependency absolves me of that.
On the other hand, if I need a graph algorithm like Bellman-Ford, I don't want to reach for a library, because that immediately forces me to use their structs for every graph node. I might also want to tune BF specifically to my graph's shapes, etc.