Live data from Hacker News

Never use a dependency that you could replace with an afternoon of programming

blog.carlmjohnson.net

211–220 of 333 posts

Re: Never use a dependency that you could replace with an afternoon of programming

#211
Adding a dependency is like adopting a puppy. Sure it seems free.. but it's not. It may be the best thing to do, but go in with eyes open on the costs.

Something like left-pad, absolutely never worth it. Something like OpenSSL, basically always worth it (warts and all). Everything in the middle, evaluate carefully.

When adopting a dependency you're adopting all their development practices. Do they break backward compatibility every minor release because compatibility is for the boring people? Never address CVEs? Every additional dependency constrains your future self by a little bit. These add up.

Re: Never use a dependency that you could replace with an afternoon of programming

#212
post #139
post #89

Earlier quoted context omitted.

Your example is more apt than intended: That's not valid json, which only allows string keys. If you use a library it'll either barf now or later when they fix it, so if you're forced to work with an API like that and can't change it, a custom parser is really the only way to go.

Well the good libraries have option flags that will allow you to handle JSON as found in the wild.

That's not JSON, though. It's absolutely something else. Maybe a JS snippet. Maybe YAML. Definitely not JSON, though.

(Some JSON libraries do have option flags, but usually it's about whether, during deserializing into a known type, unknown fields are an error or silently ignored. Or whether C-style comments are an error or considered as whitespace.)

Re: Never use a dependency that you could replace with an afternoon of programming

#213

Earlier quoted context omitted.

More generic is better. If I go into a codebase that uses standard libraries. Even if I don’t know how to do something about it someone on the Internet does. Your custom framework - not so much. I don’t have to care about how the underlying libraries work. I can treat them as a black box.

> I don’t have to care about how the underlying libraries work. I can treat them as a black box. When I wrote haskell, the majority of the libraries did just work, and I didn't have to dig into their code to find bugs often. When I wrote javascript, hundreds of the libraries I used did not just work. I usually had to care very much about their details because they were poorly implemented, full of bugs and incorrect a…

That’s also why I stay away from the clusterf%%% of front end development and JS if possible except for simple AWS Lambda scripts that have one dependency - AWS SDK.

Any other scripting I do with Python. Any more complicated development it’s using a language with an ecosystem with adults - C# or Go.

Re: Never use a dependency that you could replace with an afternoon of programming

#214

Probably good advice, but when was the last time a programmer accurately scoped a problem when they said it will take “an afternoon” to build?

I came here just to say this. "This'll take an afternoon" - three weeks later...... Programmers are notorious for this. BUT even apart from this problem ... you absolutely should use every dependency you can that will save you time. Try to write less code not more. When you write code you write bugs, add complexity, add scope increase need for testing, increase the cognitive load required to comprehend the software,…

> you absolutely should use every dependency you can that will save you time.

Absolutely. As long as it does save you that time over the foreseeable lifetime of the project. Or you are deliberately incurring a technical debt because of some deadline.

On the other hand, saving an afternoon (or even a week), over the next two weeks means very little.

Re: Never use a dependency that you could replace with an afternoon of programming

#215
post #174

Earlier quoted context omitted.

More generic is better. If I go into a codebase that uses standard libraries. Even if I don’t know how to do something about it someone on the Internet does. Your custom framework - not so much. I don’t have to care about how the underlying libraries work. I can treat them as a black box.

What do you do when the black box doesn't work? Almost everything I work with has bugs, so chances are I'm going to run into one. It's a lot easier for me to fix bugs when there are fewer layers and more of them are written by me. Of course, I can't write all the layers, but if they run on my service, I have to be prepared to fix them, or suffer from them being broken until a benevolent force fixes them for me. (Some…

Until I have to come in behind you after you’ve left for greener pastures and I have to figure out your bespoke framework and libraries.

Re: Never use a dependency that you could replace with an afternoon of programming

#217
post #174

Earlier quoted context omitted.

What do you do when the black box doesn't work? Almost everything I work with has bugs, so chances are I'm going to run into one. It's a lot easier for me to fix bugs when there are fewer layers and more of them are written by me. Of course, I can't write all the layers, but if they run on my service, I have to be prepared to fix them, or suffer from them being broken until a benevolent force fixes them for me. (Some…

Until I have to come in behind you after you’ve left for greener pastures and I have to figure out your bespoke framework and libraries.

Don't worry, I would never write a bespoke framework. I'd write a custom one. :P

Re: Never use a dependency that you could replace with an afternoon of programming

#218

Earlier quoted context omitted.

Great rule. I was wondering, how do you manage updating the Jackson JSON parsing package. What if you have 100 such packages and they get updated weekly with breaking changes ?

Only update dependencies when your code requires the new version, depends on a bug fix or it fixes a security vulnerability. Otherwise, continue using the same version. Have good test coverage to catch bugs that may originate in dependencies and subscribe to a third-party service to track vulnerabilities in your dependencies.

When you have a hundred dependencies- who is looking at the release notes to see what security vulnerabilities are being fixed?

Re: Never use a dependency that you could replace with an afternoon of programming

#219

Probably good advice, but when was the last time a programmer accurately scoped a problem when they said it will take “an afternoon” to build?

I’ve been working on the same medium-size (fewer than 1M LoC) codebase for about 7 years now. I feel like over the years, my estimates of how long something will take have gotten better for one reason: I’ve found the scaling factor I have to apply to my intuitive estimate that brings into the realm of reason.

So, if I think something looks like about a day’s work, I’ll actually estimate it at about 3.5 or 4 days. Thus, for a project to qualify as “just an afternoon,” I’d have to naively estimate it at under an hour.

I rarely have time to spare, but I also rarely go over by more than maybe a third.

Your multiplier may vary depending on how horrifying your codebase is. On a side project with good test coverage, my multiplier is only about 2.

Re: Never use a dependency that you could replace with an afternoon of programming

#220
post #160

Earlier quoted context omitted.

Great rule. I was wondering, how do you manage updating the Jackson JSON parsing package. What if you have 100 such packages and they get updated weekly with breaking changes ?

For what reason are you updating your packages? Is there a severe security issue in that package or, if it works today, could you pin it to that version and wait until there is a compelling reason to update it. Here's some reasoning - if this project was inhoused would we detect and patch it any quicker? Would we have a dev constantly assigned to it that would be pushing out patches to the rest of the team... or is i…

> if this project was inhoused would we detect and patch it any quicker?

If it's a bespoke library, no one but you and hackers directly targeting you will test for security vulnerabilities. (Good thing you have a red team... right?) For widely-used libraries, the number of vulnerabilities isn't going to be much different from your own library, but the likelihood that they're found and exploited in your system is quite lower.

So no, in most cases, you would not detect and patch vulnerabilities quicker, because you probably don't see them until it's too late.

> if it works today, could you pin it to that version and wait until there is a compelling reason to update it.

If you pin versions for a long time, eventually there comes a point where you have to update something because of a critical bug or security advisory, and of course since it's a critical bug or advisory, you have to update "right now", "priority 1", "all hands on deck", "the board is involved" and everything. The fix is in version 5.1.2 of the library, but you're stuck at 2.6.5, so now you have to do three major version upgrades (with all the changes to your codebase that entails) before you can even think about upgrading to the version containing the security fix. And that's still an easy case. If the library in question is a framework like Rails or React, version upgrades of that size may be a major undertaking that takes weeks or months to prepare, execute and validate. That's very much not fun when management is pressuring you to close that vulnerability.

I think it's never a good idea to sit on ancient libraries. Put a recurring task in your team backlog to update dependencies on a schedule. It's not going to result in less work spent upgrading, in all likelihood it's more work in terms of raw hours worked compared to the update-on-security-advisory strategy, but it's much more plannable and less stressful. That doesn't mean you have to upgrade to latest-greatest immediately (you always have the freedom to hold off a particular upgrade until the new major version has had some time to mature etc.), but there should be some time reserved on your schedule for doing your updates.

For instance, I have my update-all-lib-deps reminder in my calendar on the 1st of every even month. When it comes up, I put a task in my backlog with a checklist containing every application I have to check, upgrade and deploy. Go 1.15 just came out today, so that's going to be on my desk come October. Great timing, actually, we're going to be one or two point releases into the 1.15 branch at that point, so it's going to be a safe and easy upgrade.

Post reply on HN