Lessons from Zig
Source: Hacker News
Zig’s approach
The Zig language, created by Andrew Kelley, takes a deliberate position on standard‑library scope. The standard library focuses on low‑level, fundamental utilities: memory allocators, data structures, string operations, and cross‑platform OS abstractions. Domain‑specific functionality is explicitly excluded.
Community discussions have crystallized this position:
- In‑memory operations belong. Allocators, queues, strings, and fundamental data structures serve virtually every program.
- File‑format handling does not belong. Tar, zip, JPEG, and similar formats are considered too specialized. Each is “its own huge project” better served by dedicated libraries.
- High‑level frameworks do not belong. HTTP clients, for example, are inappropriate for a general‑purpose systems language’s standard library.
Zig does not merely avoid adding components; it actively removes them. The std-lib-orphanage repository (archived November 2025) contains code relocated out of the standard library under an MIT license, allowing community maintenance. Examples include:
realpath()was removed because it is not portable, relies on a legacy permissions model, and “is typically a bug to call”.- A red‑black tree implementation was relocated to community ownership.
- Filesystem APIs have been reorganized from
std.fstostd.Ioto better reflect their proper scope.
This willingness to shrink the standard library is remarkable. In most language communities, additions are permanent. Zig treats the standard library as a curated collection that should contract when components fail to justify their maintenance burden.
Zig’s minimalism is viable because the language ships with a first‑class package manager. Third‑party dependencies are trivially accessible. When something leaves the standard library, users are not stranded—they add a dependency and continue working.
The critical enabler: a small standard library is punitive without easy access to alternatives. With a package manager, it becomes a virtue: the standard library stays focused, and the ecosystem absorbs the rest.
The economic asymmetry in C++ standardisation
The economic structure of C++ standardisation exhibits a fundamental asymmetry. A proposal author invests finite effort across a few years. Upon acceptance, that cost terminates. The standard, however, must account for the addition in perpetuity:
- Every subsequent proposal must analyze interactions with the new component.
- Every core language evolution (concepts, reflection, contracts) must consider its effects on existing library surface area.
- Every defect report in adjacent areas potentially implicates it.
- Every compiler vendor must implement and maintain it forever.
- Every ABI concern constrains future evolution permanently.
- Every educator must decide whether to teach it.
- Every new C++ programmer must learn it—or learn to avoid it.
The combinatorial complexity of the standard grows monotonically, and this complexity tax compounds across all future committee work, forever. The proposer pays once; everyone else pays the rest.
This asymmetry creates a classic economic externality. Proposers capture the concentrated benefit of standardisation (prestige, canonical status for their design) while the diffuse, perpetual maintenance cost is socialised across all future committee participants, most of whom had no voice in the original decision.
The rational incentive is to propose aggressively and defend additions uncritically, since the proposer bears almost none of the long‑term cost they impose. Without mechanisms that force proposers to internalise perpetual costs, the standard library grows without bound.
C++ standard‑library cautionary examples
std::regex: shipped slow, cannot be fixed due to ABI constraints, and experts advise never using it for performance‑critical code.std::any: a vocabulary type nobody needed; rarely used, sacrifices type safety, frequently cited as a standardisation regret.std::auto_ptrandstd::rel_ops: took over fifteen years from recognition of defects to removal.std::codecvtfacets: deprecated, still maintained.std::filesystem: encoding assumptions frozen in 2003 produce mojibake on Windows; vcpkg “completely ripped out use of std::filesystem”.
Each seemed reasonable at proposal time. Each now imposes ongoing costs with minimal corresponding benefit. The committee lacks any formal mechanism to audit whether standardised features delivered their promised value.
Institutional decay
Samo Burja’s Great Founder Theory observes that functional institutions are the exception, not the rule. Institutions decay over time as the living knowledge that created them—the understanding of why particular decisions were made—erodes through imperfect transmission. Each generation works from “photocopies of photocopies,” and without the generating principles, the tradition cannot recover what is lost.
This pattern applies directly to the C++ standard library.
The Knowledge Problem in Standard Library Design
The design rationale, the trade‑offs considered and rejected, and the understanding of why particular API shapes were chosen—this knowledge lives in founders’ heads and dissipates when they disengage or pass away.
Beman Dawes designed std::filesystem and shepherded it for fourteen years. When he died in 2020, the living tradition of knowledge behind its design went with him. The committee must now reverse‑engineer intent from specification text.
Every component added to the standard creates another tradition of knowledge that must be preserved. A smaller standard library means:
- Fewer traditions to maintain
- Fewer succession crises
- Less accumulated complexity for future committee members to navigate
GFT’s Observation on Institutional Incentives
GFT identifies a pattern in non‑functional institutions: the body of the institution optimizes for appearance rather than function. In the context of WG21, this manifests as a bias toward adding components (visible, measurable progress) over the harder work of maintaining, improving, or removing existing ones.
- No committee member builds a career on removing
std::codecvt. - Careers are built on proposals that add.
This asymmetric incentive drives expansion regardless of whether expansion serves users.
Zig’s Contrasting Approach
Zig’s willingness to actively remove components from its standard library demonstrates a fundamentally different institutional posture: it treats contraction as legitimate progress. This requires what GFT calls a “live player”—someone with the authority and vision to make decisions that bureaucratic processes resist.
Zig’s inclusion criteria are implicit but clear:
A component belongs in the standard library only if it provides low‑level, fundamental functionality that virtually every program needs.
C++ should make this bar explicit.
When Should a Library Component Be Standardized?
A component should be standardized only when it satisfies both:
-
Stability confidence
- The design has converged over years of production use.
- No significant interface changes have been required.
- Known deficiencies have been addressed, not deferred.
-
Vocabulary necessity
- Independent library ecosystems demonstrably require type agreement to interoperate.
- Evidence exists of coordination failures that standardization would resolve.
- Third‑party distribution cannot address these failures.
“This would be useful” is necessary but insufficient. Useful libraries can thrive outside the standard. The question is: why does this usefulness require standardization rather than third‑party distribution?
Zig’s philosophy works because its package manager makes external libraries first‑class citizens. C++ lacks this, which creates pressure to put everything in the standard. The answer is not to capitulate to that pressure—it is to invest in the ecosystem.
Opportunity Cost of Library Expansion
The committee’s bandwidth is finite and precious. Every meeting hour spent on a niche library component is an hour not spent on:
- Core language improvements that benefit everyone
- Vocabulary types that resolve genuine coordination failures
- Ecosystem infrastructure that makes external libraries more accessible
The opportunity cost of library expansion is paid in delayed progress on work that only the committee can do. External libraries can be maintained by anyone; language evolution and vocabulary coordination require the committee.
The Ratchet Effect in C++
The C++ standard has historically treated removal as nearly impossible:
- Deprecation takes a decade.
- Actual removal takes even longer.
This one‑way ratchet guarantees unbounded growth.
Zig shows an alternative: when a component no longer justifies its place, relocate it. The code does not vanish; it moves to a different home where it can evolve without imposing costs on the core.
C++ cannot replicate Zig’s approach exactly—ABI stability and decades of deployed code make removal far more complex. But the committee can adopt the mindset:
- Additions should be presumed temporary, not permanent.
- Every component should periodically justify its continued inclusion.
- If a facility has known defects that cannot be fixed, acknowledging this honestly serves users better than maintaining the pretense.
The Circular Argument
- The standard library grows because the ecosystem lacks good dependency management.
- The ecosystem stagnates because everything important is expected to be in the standard.
Breaking this cycle requires choosing a direction. Zig chose ecosystem investment. C++ should consider the same.
Consequences of Continuing Expansion
- The standard becomes a repository of ABI‑frozen designs reflecting assumptions of the era in which they were standardized.
- Performance‑conscious organizations abandon
std::for internal alternatives. - The standard library becomes precisely what it was never meant to be: used at API boundaries, avoided internally.
The standard provides specification, not quality:
std::regexis specified and slow.std::filesystemis specified and has encoding bugs.
Specification guarantees portability of interface, not correctness of implementation or fitness for purpose.
External libraries can provide their own guarantees:
- Test suites
- Benchmarks
- Deployment evidence
- Responsive maintenance
These are often more meaningful to users than an ISO document number.
Teaching Implications
Beginners benefit from a coherent standard library more than a large one.
- A smaller library that works well is easier to teach.
- A large library with pitfalls requires expert knowledge to navigate.
Phrases like “use std::regex but not for performance” and “use std::filesystem but beware encoding on Windows” are not beginner‑friendly teachings.
Conclusion
The Zig programming language demonstrates that a small, focused standard library is not a limitation but a strength—when paired with ecosystem infrastructure that makes external libraries accessible.
C++ faces a different structural reality:
- No unified package manager
- ABI stability constraints
- Decades of deployed code
Nevertheless, adopting Zig’s mindset of temporary inclusion, periodic justification, and ecosystem investment can help curb unbounded growth and keep the standard library a useful, teachable foundation rather than a burdensome legacy.
These constraints are real. But they do not change the underlying economics. Every addition to the standard library creates a perpetual obligation. Every obligation consumes finite committee bandwidth. Every hour spent maintaining regretted additions is an hour not spent on work that would benefit the entire C++ community.
The committee’s most valuable resource is its collective expertise and attention. A philosophy that guards this resource—that demands rigorous evidence before accepting perpetual obligations—serves the C++ community better than one that expands the standard library in the hope that breadth compensates for the absence of ecosystem infrastructure.
Zig asks: “Does this belong in the standard library, or can the ecosystem handle it?”
C++ should ask the same question, with the same rigor, for every library proposal.
References
- Kelley, Andrew. Introduction to the Zig Programming Language
- Zig std‑lib‑orphanage. Archived November 2025.
- Ziggit: Should the standard library be “batteries included”?. 2024.
- Burja, Samo. Great Founder Theory. 2020.
- Muller, Jonathan; Laine, Zach; Lelbach, Bryce Adelstein; Sankel, David. [P3001R0] “std::hive and containers like it are not a good fit for the standard library.” October 2023.
- Winters, Titus. [P2028R0] “What is ABI, and What Should WG21 Do About It?” 2020.
- Winters, Titus. [P1863R0] “ABI – Now or Never.” 2019.
- Dos Reis, Gabriel. [P0939R4] “Direction for ISO C++.”
- Jabot, Corentin. “A cake for your cherry: what should go in the C++ standard library?”
- Winters, Titus. “What Should Go Into the C++ Standard Library.” Abseil Blog.
- R0 (2026‑02‑06): Initial draft examining Zig’s standard library philosophy and its applicability to WG21.