Honestly, the more I read threads like these, the more worried I become about whether or not I should keep writing Zig. I understand the problems that Andrew tries to solve, and I genuinely enjoy using the language.
However, the frequent changes to very often used standard library APIs in favour of some ideal which might not be realistic is beginning to worry me. Zig is a systems programming language. It might be a bad implicit assumption to say that it would always generate lean binaries, but when it fails to do so, precisely because of an āidealisticā breaking change made to such a crucial part of the standard library, one begins to wonder whether itās of any use to actually use it at all.
I donāt think the standard library, as of v0.15.2 is maintainable in anything bigger than solo projects. I wouldnāt want to use it, probably because there are so many footguns that would be associated with using APIs that tend to break frequently, and do not have the best documentation as of now. There are certain parts of the stdlib that would probably be better as external dependencies (crypto, http), and even after much discussion by the more informed people in this thread, I canāt see why, or how the new IO interface could be made practically workable.
That worries me a lot. I understand that Andrew Kelley has a very clear vision for the language, and some of his ideas have proven to be quite revolutionary (@Vector is a personal favourite, and the build system). Issues like this however, could lead to forks where people with more balanced opinions could begin to vendor their own standard librariesā¦
The way I see it (although I could be off, Iām not an insider), the language has been the higher priority thing to stabilize and has become fairly stable. The std library has been, up until recently, primarily whatever is needed for the compiler. Iāve heard several times that the std library stabilization and cleanup would come after the language is mostly stable.
So I think whatās happening now is that the std library has become a major focus. How long this will take to stabilize is unknown, and whether you have the patience to stick with it is up to you. But I donāt see any signs that it will churn forever or that bad decisions will be made. So far Iāve seen just the opposite over time.
I question whether the changes are āidealisticā. There is a need to use async IO. Providing async IO, in a way that allows switching between sync and async without changing much of your code, been a target feature for Zig for a long time and has so far not been solved and completed. So this isnāt just changes for the sake of purity or perfection, itās completion of a feature that was promised.
Perhaps its not clear that this thread is only by community members, there is no involvement from any zig team members.
Andrew is also rather clear that he wants to TRY solving various problems before he commits to 1.0 and as far as I can tell, he seems pretty receptive to the fact that it is unlikely he will solve all or even most of the things he wants to with zig.
The fact that the language is great already, the fact that Itās unlikely to solve problems he wants to; is not reason to not even try to make it better. This line of thinking is how progress is made, how new technology is made.
Itās totally understandable if you donāt want or need zig to be even better, itās understandable if you are not interested in what zig could be.
But you are not Andrew, you are not the zig team, and you are not every person using or interested in zig; you shouldnāt project your own personal experience, opinion and assumptions onto them.
Thank you very much for your thoughtful reply! I thought I was going to get flamed for a bit.
The standard library being much like a toolkit for the compiler makes a lot more sense. I was unaware of this. I think, perhaps, some of the functionality could be exposed in a better manner, or not at all? I donāt think that a standard library is meant to be roughshod in any stage of development. Maybe a leaner, better documented version would have been better for all involved. It would perhaps have been preferable for the Zig team to keep the rest private.
I am quite excited to see what Zig would have to offer in the future. I am willing to stick along for the ride, although, I will mention this that the things discussed in this thread are very real problems occuring right now. We have people who know what theyāre talking about wondering how we could make the current async implementation work.
Zig is not the only language to do this. Go has it as figured out as any language could have it figured out. I tend towards coloured functions myself, even with their resultant problems. I think that we should not delude ourselves with the state of affairs right now by saying that the problems users of the Zig compiler face are not relevant. They are, and we must admit that. Once we do so, we could have constructive discussion on how to fix said problems, instead of handling things USSR-style.
What happened to giving constructive feedback?
Or do my thoughts and opinions not matter?
Zig is pre 1.0. Ideally, this is where people are allowed to say: āGood job, but maybeā¦ā, which is what Iām doing here. Thank you for your time!
The Zig core team is definitely paying attention to the problems that come up. To be more in touch with internal discussions you can read the Zulip chat listed here.
The thrashing in std is problematic, but I donāt consider it a showstopper because std can be bypassed if itās too much. Weāre all systems programmers here and weāre not unfamiliar with having to pull out the machete and clear some underbrush.
Iām watching IoGate with interest and a bit of trepidation, but Iām also willing to let people get some experience under their belt. If I need fast I/O, Iām probably going to bypass it, anyway, for something specifically tailored to my problem. Iām happy to see people experimenting, and thatās exactly what libraries are supposed to be for. Iād kind of like to see it outside of std, but, meh, I can deal.
Iām FAR more concerned when people start proposing to make the language or compiler do weird things in order to support a library. No. Do not do that. That is the wrong way around.
You should always assume that there is a better abstraction that a library could support. Libraries should thrash several times before you even begin to consider that the language or compiler should mutate. And, even then, maybe there just should really be two different libraries as not everything can always be reduced to the āOne Best Solutionā¢ā in all cases.
Sure, maybe sometimes the language does need something new. However, you normally need multiple programs and multiple libraries pointing at something and saying āHey, we could get a lot better if we just had this simple thingā before considering it.
I donāt want a language to be encased in amber, but I definitely want people to spin their wheels making library abstractions a lot before declaring that the language or compiler should do something weird.
To me, it seems like there is a bit of a clash in ideologies of Zig users:
You have the more system programming minded people who are unwilling to compromise on certain details like binary sizes and the cost of virtual tables.
Then you have the more application driven developers who are willing to give up a few cycles here and there or a few hundred KB in their binary to commit to some more āideologicalā paradigm in exchange for a more generally useful language.
My observation is that Andrew has been appealing more to the former crowd up until now, and now that the language is closer to maturity, he is focusing more on the bigger picture. After all, the first statement on the Zig website is that it is a āgeneral purpose programming languageā. Perhaps that explains some of the discontent in this thread.
Makes you wonder where the happy middle ground is of a ābatteriesā included standard library and bare metal programming. Surely there exists some appeal in Zig as is, otherwise system devs would just stick to C and application devs some other āuser-friendlyā language.
My two-cents is that if you are really in such a constrained environment that a few hundred Kb of binary size and the cost of virtual tables are critical, then you most likely should not rely on a āgeneral purposeā standard library. For example, embedded software tends to want completely different abstractions for things like IO anyways; std.Io is designed for a generic Windows/Posix compatible system, so clearly it is not the most obvious choice. Maybe the solution is to use a library more targeted for embedded, who knows.
I would add that when we have many IO implementations to choose from and we know how to make more, I think there wonāt be as many all-or-nothing tradeoffs even when we do use the IO interface.
Thatās not proven as yet, but for my part, I have some faith in this teamās ability to not get stuck in a local maxima.
Most languages seem to follow the heritage of packaging a āstandardā lib⦠some fatter, some skinnier. A āgeneral purpose programming languageā (zig) will naturally want the same, but when I glanced a long time ago, it already looked like the zig embedded community was happy with std-less zig⦠could not zig evolve into a language (ātheā language?) with choose-your-own stds, maintained by sanctioned core teams? applib, syslib, rtlib, ā¦? Zig would have to be robust enough to support all. Everybody would still argue about what belongs where, and there would be some duplication, even if the lib structure was tiered or more granular. But couldnāt it work? vtable io would go in applib; core io might go in syslib, and be accessible only directly (no async vtables) - possibly a generics-based model would provide a level of comptime abstraction more fit for systems-level patterns? Real-time/embedded devs might want the bare-metal and rtos work that many in that domain have been building (I think). There might be a bit of messiness - things done a little differently here and there, which is what weāre used to with aftermarket libs, but if focused core libs were at least as good as aftermarket competitors, and had the sanction of core devs (and the security that came with that), then who cares?
I donāt really think that itās a good thing for any language to have a standard library that should be bypassed. Normally, I FFI into C or use another programming language if I come up with something that Iād like Zig to do, which it canāt do yet. Thatās a non-issue. Zig is such a great language that its std is not a limitation. Also, itās pre-1.0, so I understand that these are the challenges being faced.
That is true. I agree with this completely. But, it makes IOGate look worse, in my opinion. Again, I understand that Andrew Kelley is trying to achieve something new with async, but, again, this is a problem that Go has solved. Itās not niche. So, I might go as far as to say that itās a step in the wrong direction, but I have full confidence that the team would figure out how to solve it.
A very fair, a very complete opinion. When is that, for Zig? Mature libraries in Zig is a concept that might be difficult to express because of the churn that comes with every update to the standard-library. This is a concept thatās very, very difficult to express given Zigās current internals, even though @LucasSantos91 has already given a vision of what he thinks could be done, which is entirely fair, and brings hope that the reference of the language would not need to be updated to secure good IO
I think that if you have bloat of more than 10x on a āHello Worldā, then that might creep into other cases in which you would need smaller binaries? In this case, smaller is always better, no matter the edge-case. Regressions like these are worrying. I have stated, and I will keep stating, that it is obvious that Andrew Kelley knows his bollocks.
Many people seem to say things like ādifferent IOā implementation, or ādifferent librariesā, but weāre not there yet, and we may not be for some time. I think that if the Zig team, in future releases were able to actually work on the standard library by pruning its excesses, to expose something bare-bones, well documented, and rock solid, there would be no need for external standard libraries because the stdlib already does what its supposed to do as a systems language. Your standard library does not need to be as fat as rusts or as whatever the hell C++ās is.
FWIW I think the main reason why C is alive and kicking is that it works just fine without using the C stdlib. The C stdlib is stuck deep in the K&R era and thoroughly outdated, but using C without the stdlib is just fine (especially since the only āgood partsā of the stdlib, e.g. memcpy and memset have essentially become compiler builtins).
PS: a rich stdlib is great when it exists, but IMHO there should be a clear separation line between language and stdlib, itās a good thing when the language is usable without (most of) the stdlib (because also IMHO: the entanglement of language features and stdlib is what killed āmodern C++ā).
I agree completely. I argue for a good standard library, instead of a bad one. We donāt need a rich one, we need something barebones and well documented. Cover the basics, nothing else. Document it well, and export performant APIs.
My complaint is this: If we have standard library APIs that exist, they should be solid, and well documented. If we donāt have that, donāt expose any at all. Itās fine not to have anything other than what works. And clearly, some of the ideas might need to spend longer in the incubator (the new IO interface). Thatās it.
The language is more than good enough on its own. Thank you!
On the whole I really enjoy reading your commentary.
I agree with a lot of it and you argue well for the points I donāt agree with. But this:
I think thatās just factually wrong and giving Andrew and the Zig team too little credit here.
Go solves the problem by enforcing a specific concurrency model. Itās a very useful and well thought out concurrency model, granted, but if you want to depend on code that does not fit in Goās model of concurrency, itās inefficient and annoying. A lot of languages can be used similarly as long as you āonlyā use the async part of the language, but⦠well, thatās the whole issue, right?
Zig is attempting to solve the problem by letting libraries abstract over the concurrency model instead. Thatās a way more useful āshapeā to the solution, because it means application developers do not have to rely on library developers developing libraries with a specific model in mind.
Go solves the function coloring problem by providing a machine that makes any paint look red if you squint, while Zig solves it by handing you a manual on paint mixing and saying āif youāre fine with just blue or red weāve got it in stockā.
I donāt agree with the direction the current std.Io is taking, but I think that can be worked out later. The framework of thinking about concurrency as a different primitive from asynchrony, which is what enables abstracting over the concurrency model, that is a super useful innovation.
Thank you very much for your comment.
I will admit that I was a bit ungracious in my comments on what Zig was trying to achieve. Generalizing Goās solution of colourless async functions over Zig was not very nice of me. I apologize for it.
To borrow some insight from the rust community, eventually someone did make an async executor for embedded that fit the same niche as an RTOS but without the need for an OS.
I havenāt used it and my information is a bit outdated, but it seems to be pretty popular and well maintained from the outside, so I assume it works well.
I guess I just donāt see why this would scare you off so much. The language is literally STILL not at 1.0 right now the language is being used in production settings, but to write the language off becuase a pre 1.0 decision is made about Io, easily one of the hardest problems in programming to solve seems to me to be a little⦠knee jerk?
āI donāt think the standard library, as of 0.15.2 is maintainable in anything bigger than solo Projects.ā
There are plenty of real world team projects using zig and the std so I think this is a you problem entirely.
ā
Hard disagree, I rather not have the JS ecosystem where everything is a dependency attack vector and in 2026 these are both things that should be held very close to the chest.
I feel like you are reading an entirely different thread, there have been numerous ideas brought forward on how to solve this 1 problem, special casing Io being one of them which to me every language in some way has to special case it if they wish to have some type of language level support for it.
This all seems very knee jerk for a feature that isnāt even in a stable release yet and hasnāt even had one round of warranty fixes.
Iāve probably āsufferedā more than most due to the std lib churn. My projectās 0.16 branch is currently 3,423 additions and 6,269 deletions, and the changes to support 0.15 were 4,943 additions and 1,254 deletions (I had to temporarily vendor the 0.14 zlib code but still, most of those changes were mine and done by hand).
This kind of work is not fun at all, and it slowed down feature work, but itās hard to complain ā my project is better with the new Reader/Writer interfaces. While the jury is still out on Io, it will likely make it much easier for me to add multithreading. IMO the Zig team is right to push aggressively here for the best design in the std lib. That saidā¦
The one thing I wouldāve done differently is be less aggressive about deleting deprecated parts right away. They couldāve left the old zlib code in there one more release alongside the newer code that uses the new Reader and Writer, saving me from manually vendoring. And in 0.16 they are deleting many lower level posix functions right away ā I wouldāve left them in for at least one more release. Accounting for all these breakages is much harder when you have to do all of them at once.
At any rate, if you are looking for std lib stability, you came to the wrong town :^D I personally signed up for this, and the Zig team is moving mountains right now so I gotta give them some slack.