If you look at my portfolio[0], you’ll see it packed with things like widgets and adornments. Most of these, I use in my own projects. I eat my own dog food.
But today’s languages, with their reliance on extensibility and interfaces, makes writing standalone code assets a lot less cumbersome. I write in Swift, and there are some pretty big Swift "extension suites" out there[1]. The Apple Swift Package Manager is nice, too[2].
It's just that when I write a code module, I do it as a standalone product, with a full test suite (usually a harness[3], which often takes the form of a "full-fat" application), and a unique release management cycle.
My modules are pretty independent, so they aren't usually custom-tailored for all of their implementations; acting in a fairly general capacity.
[0] https://stackoverflow.com/story/chrismarshall
[2] https://swiftpackageindex.com
[3] https://littlegreenviper.com/miscellany/testing-harness-vs-u...
What's really missing is the willingness to say "no". There's pressure to put fancy or trendy toys into applications to look up to date or to get experience on the latest fads. KISS and YAGNI are often ignored for eye candy or Fear of Falling Behind.
For example, fairly early in the 2000's I had a web form that only did server-side date validation. It worked just fine. But client-side date validation was becoming "expected" because everyone started doing it and the manager asked me to put it in. So I found a JavaScript component on the web, and it worked fine at first. But a few months later a bug was found in it that appeared on a certain date, and it generated a lot of phone calls from users. Those phone calls would have never existed had I gone with my gut and left it out. Few users are going to spend all day making date errors such that client-side date validation is NOT necessary. It's a me-too toy.
Warren Buffett often cites his ability to say "no" as to why he's so wealthy. He looks at the actual tradeoff numbers, not peer pressure.
But you can have modularity within a single codebase and some languages / build-systems allow you to define very clear boundaries between your different modules. In that case, I don't think you have necessary a lot of code duplication (you might have slightly increased consumption due to the use of more indirection). But you might have to code to interfaces and explicitly eliminate coupling etc.