logoalt Hacker News

bob1029yesterday at 8:50 AM26 repliesview on HN

"Batteries included" ecosystems are the only persistent solution to the package manager problem.

If your first party tooling contains all the functionality you typically need, it's possible you can be productive with zero 3rd party dependencies. In practice you will tend to have a few, but you won't be vendoring out critical things like HTTP, TCP, JSON, string sanitation, cryptography. These are beacons for attackers. Everything depends on this stuff so the motivation for attacking these common surfaces is high.

I can literally count on one hand the number of 3rd party dependencies I've used in the last year. Dapper is the only regular thing I can come up with. Sometimes ScottPlot. Both of my SQL providers (MSSQL and SQLite) are first party as well. This is a major reason why they're the only sql providers I use.

Maybe I am just so traumatized from compliance and auditing in regulated software business, but this feels like a happier way to build software too. My tools tend to stay right where I left them the previous day. I don't have to worry about my hammer or screw drivers stealing all my bitcoin in the middle of the night.


Replies

rhdunnyesterday at 5:19 PM

There are several issues with "Batteries Included" ecosystems (like Python, C#/.NET, and Java):

1. They are not going to include everything. This includes things like new file formats.

2. They are going to be out of date whenever a standard changes (HTML, etc.), application changes (e.g. SQLite/PostgreSQL/etc. for SQL/ORM bindings), or API changes (DirectX, Vulcan, etc.).

3. Things like data structures, graphics APIs, etc. will have performance characteristics that may be different to your use case.

4. They can't cover all nice use cases such as the different libraries and frameworks for creating games of different genres.

For example, Python's XML DOM implementation only implements a subset of XPath and doesn't support parsing HTML.

The fact that Python, Java, and .NET have large library ecosystems proves that even if you have a "Batteries Included" approach there will always be other things to add.

show 7 replies
wongarsuyesterday at 10:40 AM

> In practice you will tend to have a few, but you won't be vendoring out critical things like HTTP, TCP, JSON, string sanitation, cryptography

Unless you are Python, where the standard library includes multiple HTTP libraries and everyone installs the requests package anyways.

Few languages have good models for evolving their standard library, so you end up with lots of bad designs sticking around forever. Libraries are much easier to evolve, giving them the advantage in terms of developer UX and performance.

show 5 replies
afavouryesterday at 11:58 AM

Irony is that Node has no need for Axios, native fetch support has been there for years, so in terms of network requests it is batteries included.

show 8 replies
dec0dedab0deyesterday at 3:30 PM

Batteries included systems are still susceptible to supply chain attacks, they just move slower so it’s not as attractive of a target.

I think packages of a certain size need to be held to higher standards by the repositories. Multiple users should have to approve changes. Maybe enforced scans (though with trivy’s recent compromise that wont be likely any time soon)

Basically anything besides lone developer can decide to send something out on a whim that will run on millions of machines.

show 2 replies
zdc1yesterday at 9:21 AM

The other thing that keeps coming up is the github-code-is-fine-but-the-release-artifact-is-a-trojan issue. It really makes me question if "packages" should even exist in JavaScript, or if we could just be importing standard plain source code from a git repo.

I understand why this doesn't work well with legacy projects, but it's something that the language could strive towards.

show 3 replies
cozzydyesterday at 3:13 PM

or you don't use a package manager where anyone can just publish a package (i.e. use your system package manager). There is still some risk, but it is much smaller. Like, if xz were distributed by PyPI or NPM, everyone would have been pwned, but instead it was (barely) found.

It's true that system repos doesn't include everything, but you can create your own repositories if you really need to for a few things. In practice Fedora/EPEL are basically sufficient for my needs. Right now I'm deploying something with yocto, which is a bit more limited in slection, but it's pretty easy to add my own packages and it at least has hashes so things don't get replaced without me noticing (to be fair, I don't know if the security practices of open-embedded recipes are as strong as Fedora...).

show 1 reply
rendawtoday at 6:19 AM

This just moves the trust from one group to another. Now the standard library/language maintainers need to develop/maintain more high quality software. So either they get overworked and burn out, don't address issues, fail to update things or they recruit more people who need to be trusted. Then they are responsible for doing the validation that you should have done. Are they better equipped to do that? Maybe they go, oh hey, Axios is popular and widely trusted, let's make it an official library and bring the maintainers into the fold... wait isn't this exactly where we started?

What process did you trust the standard library/language maintainers in the first place? How do they differ from any other major library vendor?

mrsmrtssyesterday at 9:11 AM

Fully agree with this! I think today .NET is probably the most batteries included platform you can get. This means that even if you use third-party libraries, these typically depend only on first-party dependencies, making it much less likely for something shady to sneak in.

show 5 replies
junonyesterday at 9:08 AM

This is a rather superlative and tunnel vision, "everything is a nail because I'm a hammer" approach. The truth is this is an exceedingly difficult problem nobody has adequately solved yet.

show 1 reply
tliltocatlyesterday at 2:51 PM

I agree that dependencies are a liability, but, sadly, "batteries included" didn't work out for Python in practice (i. e. how do I even live without numpy? No, array aren't enough).

show 1 reply
Lord_Zeroyesterday at 2:43 PM

So, youre on Microsoft then, judging by ScottPlot you write .NET desktop apps. If you use Dapper, you probably use Microsoft.Data.SqlClient, which is... distributed over NuGet and vulnerable to supply chain attack. You may not need many deps as a desktop dev. Modern day line of business apps require a lot more deps. CSVHelper, ClosedXML, AutoMapper, WebOptimizer, NetEscapades.AspNetCore.SecurityHeaders.

Yes less deps people need the better but it doesn't fix trhe core problem. Sharing and distrib uting code is a key tenant of being able to write modern code.

fireanttoday at 3:00 AM

While it's true that the packages are first party, .NET still relies on packages to distribute code that's not directly inside the framework. You still probably transiently depend on `Microsoft.Extensions.Hosting.Abstractions ` for example - if the process for publishing this package was compromised, you'd still get owned.

raincoleyesterday at 2:39 PM

Different programmers have very different ideas about what is "all the functionality you typically need."

troadyesterday at 11:14 AM

What are some examples of batteries-included languages that folk around here really feel productive in and/or love? What makes them so great, in your opinion?

(Leaving aside thoughts on language syntax, compile times, tooling etc - just interested in people's experiences with / thoughts on healthy stdlibs)

show 3 replies
binsquareyesterday at 4:21 PM

yep!

This is exactly the world I'm working towards with packaging tooling with a virtual machine i.e. electron but with virtual machines instead so the isolation aspect comes by default.

invaliduseryesterday at 11:05 AM

For a lot of code, I switched to generating code rather than using 3rd party libraries. Things like PEG parsers, path finding algorithms, string sanitizers, data type conversion, etc are very conveniently generated by LLMs. It's fast, reduces dependencies, and feels safer to me.

show 2 replies
gedyyesterday at 11:46 AM

> "Batteries included" ecosystems are the only persistent solution to the package manager problem.

The irony in this case is that axios is not really needed now given that fetch is part of the JS std lib.

jaikechentoday at 1:32 AM

I think stay vigilant is better than trust anything.

christophilusyesterday at 9:43 AM

Honestly, you can get pretty far with just Bun and a very small number of dependencies. It’s what I love most about Bun. But, I do agree with you generally. .NET is about as good as I’ve ever seen for being batteries included. I just hate the enterprisey culture that always seems to pervade .NET shops.

show 1 reply
EGregtoday at 12:39 AM

Not at all. We simply need M-of-N auditors to sign off on major releases of things. And the package managers need to check this (the set of auditors can be changed, same as browser PKI for https) before pulling things down.

That's the system we have in our Safebox ecosystem

pier25yesterday at 1:10 PM

I agree. Got downvoted a lot the other day for proposing Node should solve fundamental needs.

TZubiriyesterday at 1:10 PM

But javascript is batteries included in this case, you can use xmlhttprequest or fetch

gib444yesterday at 9:39 AM

What kind of apps do you build / industry etc?

philipwhiukyesterday at 3:01 PM

Language churn makes this problem worse.

Frankly inventing a new language is irresponsible these days unless you build on-top of an existing ecosystem because you need to solve all these problems.

commandlinefanyesterday at 5:05 PM

> "Batteries included" ecosystems are the only persistent solution

Or write your own stuff. Yes, that's right, I said it. Even HTTP. Even cryptography. Just because somebody else messed it up once doesn't mean nobody should ever do it. Professional quality software _should_ be customized. Professional developers absolutely can and should do this and get it right. When you use a third-party HTTP implementation (for example), you're invariably importing more functionality than you need anyway. If you're just querying a REST service, you don't need MIME encoding, but it's part of the HTTP library anyway because some clients do need it. That library (that imports all of its own libraries) is just unnecessary bloat, and this stuff really isn't that hard to get right.

show 2 replies