Hacker News new | past | comments | ask | show | jobs | submit login

Dependencies are cattle, not pets. There's nothing wrong with having zillions of them; what you need is good tools to manage them in bulk.

In the JVM ecosystem, projects are only allowed in the Maven Central repository if they have their license documented in a machine readable fashion there; it's then trivial to check what licenses you're depending on (and there are several plugins available for doing so). I'm amazed other ecosystems don't offer the same.




> Dependencies are cattle, not pets.

That doesn't make any sense. That analogy works for mostly-identical computers, where if your software won't run on one computer you can just use another mostly-identical computer.

Almost by definition dependencies are not interchangeable. You can't replace a routine to pad strings with a routine that is a web server. Or a matrix multiplier. Even dependencies that do the same overall job almost never have the same API. Heck, even the same dependency often ends up with a different incompatible API over time as versions change.

> There's nothing wrong with having zillions of them; what you need is good tools to manage them in bulk.

Every added dependency is a risk. Each unintentional vulnerability in each dependency increases the number of vulnerabilities that might be exploitable in your system. And that's just the unintentional vulnerabilities.

Practically all systems provide no useful sandboxing between dependencies, so if any one of your transitive dependencies is malicious, then your entire system is malicious.

Every new dependency also brings in potential license issues, per this article. I think it's unacceptable to have a scarefest about the AGPL, GPL, or LGPL; for a vast number of applications those licenses are just fine. The bigger risks are software that has no license at all, which are a legal risk for any project that uses them until governments change international treaties involving copyright (which is not likely any time soon). But it's certainly true that various licenses are not acceptable for certain situations, and every new dependency increases the risks of licensing problems.

Having no dependencies is absurd; it's uneconomic to build everything from scratch. But every time you add a dependency you need to think about the trade-off; it is sometimes wise to not reuse something.


> Dependencies are cattle...

... Which also happen keep their own cattle that you're still responsible for.

It's not so bad in languages with solid standard libraries. In Python projects I might have 20 direct deps, ~50 indirect.

In a real JS project I'm building, I have 17 direct, 3829 indirect. The JS standard library is so damned thin that everything pulls in some random version of the kitchen sink.

    yarn list | sed -E 's/.*─ //' | sort -u | wc -l  # minus 2
In situations like that your job of auditing licenses, updates, sec issues, etc balloons exponentially with each new dependency.

Tooling should absolutely be used, but it still doesn't perform the job of working out whether or not you want to upgrade a component, or whether or not you're likely to have suffered a security breach, or how to report on how well audited your dependencies are.


"Servers are cattle, not pets" relies on the servers being substantially identical, cloned like bananas from a single source where each is as good as the other.

Dependencies are, if they are to be useful at all, all different. Dependencies are suppliers, in the business sense. Having lots of dependencies loaded at runtime is like a modern just-in-time giant supply chain; it lets you take advantage of efficiencies in exchange for being more brittle.

Or they are like BOM items on a circuit board. Part of the original drive to "componentise" software came from people experienced in electronic engineering; you don't have to reinvent the transistor, you just buy them at a cost of a few dollars for a reel of thousands. But experienced designers will still try to:

- choose more-common components wherever possible

- ensure there are multiple sources for a component

- reduce the overall number of BOM lines, which reduces supply risk and inventory cost

The software world would go completely bananas if the cost for dependencies was not exactly zero. Imagine having to license left-pad.


> There's nothing wrong with having zillions of them...

There's nothing wrong until something goes wrong an now you're royally screwed. With zillion dependencies you are at a mercy of zillion maintainers, and none of them has any obligation to you. They can break backwards compatibility in patch releases, introduce subtle behavior changes, steer the project in an unexpected direction or abandon it altogether.


I’m a bit torn on this. I have most of my experience in the .NET ecosystem, where dependencies are a lot more manageable. However, if something breaks, you’re screwed a lot harder, because it’s not so easy to replace a large library, and there are very likely fewer well-maintained alternatives than there would be on NPM.

In total, I find it hard to deny how productive the NPM ecosystem can be, despite my philosophical objections to the way the community is run. Am I crazy here?


You aren't alone in this. The Node/NPM/JS scene is churning out code and innovations like there's no tomorrow, that's something to admire.

What I feel they are missing is a community process to consolidate things. You don't need three generations of ten incompatible solutions for a given problem - after some iterations, things should consolidate into one or two more or less standardized libs that don't break existing code at every damn point release.


> You aren't alone in this. The Node/NPM/JS scene is churning out code and innovations like there's no tomorrow, that's something to admire.

I don't find churning out code admirable, and I also don't think I've seen any true innovation come out of the NPM scene (bar innovation in the browser/JS space itself, which I think isn't a good measure as it's mostly just working around limitations that shouldn't be there in the first place).


That goes into the direction of my thinking. I am concerned about transitive security issues. It is impossible to check in node dependencies into version control (size/binaries). They have a lock file to pin versions, but dependencies that are downloaded upon each build are are not reproducible from my point of view. With Go, it’s easy to vendor and check in, it’s also straight forward to review them. There have been examples of targeted attacks using npm packages and that is something I am very concerned about.

People move billions with a node.js application we develop and the company will eventually be liable if the system is compromised through a targeted attack.

On a different note, I think the ecosystem moves too fast, packages and versions are getting deprecated and new ones getting released constantly. I have the feeling that the whole ecosystem is targeted towards building small MVP apps, not relying a long-term business on it. Maybe I am too harsh here, but that is a frustration growing for years now. I am happy to be proven wrong.


Not a huge fan of node or anything but npm lock files do pin to a hash. Also in commercial world you're going to be pulling through nexus or some other cache to reduce bandwidth use and developer downtime.

Are there other reproducibility concerns I should be worrying about? Are you thinking npm modules with native code or that (this does happen!) actively pull other stuff during build? Most of those do their own pinning but agree the whole thing is messy.


> There's nothing wrong with having zillions of them

That is a scary point of view. We have forgotten that there is no such thing as a zero-cost abstraction, apparently, and shovelware developers are now employed by enterprises and write enterprise software...

CPUs aren't getting faster. Software is getting slower a LOT faster than hardware is getting faster, these days, and people are still apparently perfectly fine with adding dependency upon dependency upon abstraction upon abstraction and it's adding up extremely quickly.

A good first step to addressing this is to favor a small copy & paste operation over a small dependency. Lots of people will shriek at the idea of this, but I promise you, all the problems with copying and pasting code are nowhere nearly as severe as all the problems with dependencies. Working to avoid problems you don't have results in creating problems that you definitely do have.


The comment you're replying to makes references to the JVM, which is not surprising given what I've seen in the Enterprise Java culture.


This protects you against licences you don't expect, but not against malicious or subverted dependencies.

Since a dependency can generally do anything your application has privileges for, widely depended-on libraries are an attractive target. A cattle approach means more dependencies, and it being easier for new ones to sneak in.


In that case the npm ecosystem has some serious bovine spongiform encephalopathy risks to manage


> Dependencies are cattle, not pets.

It depends on your context. Sometimes, dependencies are not pets, but weights on your airplane.


> what you need is good tools to manage them in bulk

How do you manage reputation and relationships in bulk? There are transactional costs here. Dependencies created by maintainers with impeccable reputations are a much smaller risk than arbitrary dependencies created by arbitrary maintainers.


You require releases to be signed by maintainers (again, something maven central enforces and other repositories ought to), and then you have a notion of maintainer identity and can decide which you trust (again something that plugins let you do). If there are still too many maintainers then you can use the GPG web of trust approach, as e.g. Debian does, and see which maintainers are part of trusted organisations.


Does Maven Central also require machine-checkable proofs of security?


No (and I don't think any code repository does or could; what would a "proof of security" actually prove?). It does require machine-checkable signing of all releases.


The opposite of this is true.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: