5 ms·
A former boss of mine had a sign above his desk: “Transitive dependencies are the lifeblood of stuff. We don’t build stuff, we build software.”. While I am not
by _asummers 8y ago
A former boss of mine had a sign above his desk: “Transitive dependencies are the lifeblood of stuff. We don’t build stuff, we build software.”. While I am not a JS developer, I am distrustful of every dependency brought in and aggressively work to eliminate the only kind of useful ones. They’re debt brought into the code base and must be constantly evaluated for security concerns, interactions with other dependencies, and upcoming changes being incompatible with your code, which may in turn cause you to be unable to upgrade other dependencies.
Not having to write code is great, but when you bring something in it becomes code you must maintain for however long it is in your project. The utility calculus is variant for all projects and even different phases of the same project. But the calculation should be done often and ones that fall below the utility threshold should be removed.
- chii 8y agoAnd at what utility threshold should one ought to take a lib vs self-write? Unless you're deeply experienced, it's a very hard judgement to make. Plus the time spent investigating is not small either. My rule of thumb is to take a lib if it's not you're core concern, and write your own if it is. You only have one core concern in a project, and that's what the customer pay for.
- _asummers 8y agoIt's different based on each dependency and where you're at in the project lifecycle. If you're running as fast as you can to get off the runway before you crash, you have more of an incentive to bring it in and punt the problem down the road. But after that point passes it should be reevaluated. You should know every dependency in your code and why it's there. For me, I find that it's a function of overall value to your code, number of issues you've had with it, overall size, ability to understand the code relative to what it's doing, and project health. Again, the calculus is different for everybody, but the important aspect is that you're consciously thinking about the utility of the dependency. An ORM is hard to write, is often hard to read, but provides extreme value, and hopefully has a large community to quash issues and contribute to the project's health. To borrow an extreme example, left pad is not. Even if left pad is not in your core competency, that's not something that should be brought in because you can write your own. Even left pad may be subject to the event-stream style attack, and it being out of your control is risk you're bringing into your project. Risk management is tricky, and you'll never get to 0 risk, but you should try to minimize it where you can reasonably do so. It's all about balance.
- bfrydl 8y agoOne thing to note about create-react-app is that nearly all, in fact almost literally all, of those dependencies are development tools. They are also a pretty “normal” configuration of tools, based on standards rather than some custom framework. This means that if you have a problem with create-react-app or it were to be abandoned, you could just get a different development tool and likely make zero changes to your actual code.
- _asummers 8y agoFor sure, I'm not necessarily commenting on this particular example, as I'm unfamiliar with the tooling brought in by that command, and don't use JS myself. It's more of a comment about software dependencies in general. I'm usually much more tolerant of development dependencies than production dependencies.
- everdev 8y ago> I am distrustful of every dependency brought in Ever look in your node_modules folder? I dislike the JS ecosystem for this very reason. It's so common to find dependency soup in any non-vanilla JS app.
- _asummers 8y agoNot in JS, but yes I do. Often. A useful exercise is trying to just bump everything one at a time and seeing where you can't. Tooling helps with this, but I usually do this reevaluation task when I go to do dependency bumps. "Why can't I bump this dependency to its current version?" usually causes me to reevaluate the dependency thoroughly. Many times it results in just making an upstream PR, but sometimes the decision is made to inline the parts that are used. As an example, we had a dev dependency that all it did was print tables with borders for pretty printing test failures in some capacity. When I went to do a language bump, it was incompatible, so I rewrote it in 10-15 lines using the standard language library. At the time, it was helpful, but it overstayed its welcome by preventing a language upgrade. As a counterexample, our ORM has caused me extreme strife this month because it changed a feature we were relying on heavily. That resulted in a bunch of work, but the dependency is so useful to our project that I would not have considered rewriting it.
- pcmaffey 8y agoSign above Newton's desk: "If I have seen further it is by standing on the shoulders of Giants." We can strive for sustainability and autonomy, but we're forever dependent on each other's work. As they say, it's turtles all the way down.
- echelon 8y agoYes, but there is a lot of nuance here. Introducing dependencies is a quick way to get to market since you don't have to build a universe from scratch. Once you've gotten to market, you have to support your thing. This is when dependencies start to have a non-zero cost. When you'd rather spend engineering efforts on building new features, you instead have to do regular house cleaning to make sure your thing continues to work and have a happy upgrade path. The larger the engineering organization you work in, the more apparent this becomes. Smaller orgs can sometimes brush the ugly under the rug. Larger ones bump into issues constantly. I'd wager that 5% to 10% of engineering might be dealing with maintenance of dependencies. (fwiw, I'm mostly speaking in terms of my experience as a backend engineer.)
- _asummers 8y agoYou are seeing to the heart of my argument. Thank you for that. I agree on the 5-10% mark, and find it's true even in smaller orgs that have a mature enough product. Once the product solidifies, having a bunch of different dependencies dictate which direction you can go is not in the best interest of the company, and should be reevaluated accordingly.
- _asummers 8y agoTo thoroughly abuse the metaphor, you don't always want to go where the giant goes. Sometimes you would like to climb down and walk your own direction. Dependencies can take you near where you want to go, and if they can take you all the way there, terrific! Use them for as long as you can! But if you're not directing the giant, you're subject to its whims. And the more people standing on the giant's shoulders, yelling in its ears where they want it to go, the harder it is to make sure it's going where you want. At a certain point, this risk outweighs the rewards, and you adjust accordingly.
- deleted 8y ago[deleted]