Build It Yourself
Modern languages with rich package ecosystems, especially Rust and JavaScript, make it extremely easy to pull in large trees of third‑party dependencies for even simple tasks. Commenters weigh the productivity benefits of reusing mature libraries against long‑term costs: security risk, churn from transitive updates, loss of control and understanding, and the difficulty of auditing what actually ships. Many argue for a middle path—using dependencies for genuinely hard, general problems (e.g., crypto, HTTP stacks) while deliberately inlining or hand‑writing small, stable utilities to keep dependency graphs shallow and maintainable.
Rust’s Dependency Culture & Small Standard Library
- Many compare Rust to Go: typical Go services have ~10–20 (including transitive) deps, while even small Rust projects, especially async ones, quickly hit 100+.
- Main cited reason: Rust’s intentionally small stdlib (no HTTP, logging, time, regex, etc.), versus Go’s large, batteries‑included stdlib.
- Rust stdlib maintainers (represented in the thread) emphasize:
- API stability over decades, no “Rust 2.0”.
- Need to experiment and break APIs in crates before blessing anything into std.
- Limited maintainer capacity and slower release cadence for std compared to crates.
Comparisons with Other Ecosystems
- Go praised for stdlib, tooling, and relatively low dep counts; “TinyGo” and no‑std Rust mentioned for embedded, but some see “small stdlib for embedded” as an overused justification.
- Java, C++, .NET: larger stdlibs but also historical baggage (e.g., multiple date/time APIs in Java; C++ std parts people say “don’t use”).
- JS/npm and Python/PyPI used as negative examples of extreme dependency churn and left‑pad‑style micro‑packages.
Pros & Cons of “Build It Yourself”
- Pro‑DIY side:
- Small, self‑contained utilities (≤100–200 LOC) are often more stable, easier to reason about, and immune to upstream churn.
- Dependencies are tech debt: upgrades, breaking changes, abandoned projects, and security advisories all cost time.
- AI tools make generating small, dependency‑free helpers faster than wiring libraries.
- Pro‑library side:
- Real‑world domains (terminals, HTTP, crypto, parsing, FHIR/HL7, logging, async runtimes) hide big edge‑case surfaces; bespoke code often underestimates complexity.
- General libraries handle unknown‑unknowns and cross‑platform quirks (e.g., terminal sizing on various Unix/Windows flavors).
- Re‑implementing complex things (HTTP servers, crypto, DB drivers, regex engines) is seen as risky or wasteful.
Security, Trust & Distribution
- Some argue OS distros and shared libraries provide an extra review and patching layer versus uncurated registries (crates.io, npm, PyPI, Docker Hub).
- Others respond that distro maintainers cannot meaningfully audit huge modern stacks either; human fallibility remains, as shown by recent supply‑chain incidents.
- Debate over whether vendoring/forking dependencies improves security (local control) or just shifts maintenance burden.
Tooling, Features & Possible Mitigations
- Cargo features allow trimming optional functionality, but ergonomics favor enabling over disabling, and propagating fine‑grained control through multiple layers is cumbersome.
- Some want curated “blessed” sets of crates or a growing stdlib that periodically folds in de‑facto standards (e.g., regex, time, logging).
- Others argue Rust’s current model (small stdlib + powerful package manager) is acceptable, and dependency minimalism is a project‑level cultural choice, not a tooling limitation.