I consistently use X.Y.Z names to refer to the numbers as shorthand independent of semantics.
Some of this is a misuse of zerover. (Fun site! Documents some huge name "offenders" which are still version 0.Y despite being widely used.) A number of crates (but thankfully, primarily smaller ones) tend to bump Y for new minor, API-compatible features the way you would for X≥1, despite still being on X=0. Semantically, they're doing 0.MAJOR.PATCH versioning, without a minor version number.
This is problematic (and especially so for public dependencies), because you're creating an API incompatibility where none exists. The proper practice is 0.MAJOR.MINOR, where additions are made compatibly when they are.
It's also true that the semver specification states that once you're concerning yourself with backwards compatibility, you should be on version 1.0. There's some truth to the value of 1.0 to advertise stability, but it's only actually beneficial if your timeframe of stability pretty closely matches the library's idea, and it's worth noting that Rust has a much stricter idea/definition of what's API stable than a lot of other languages (especially dynamic ones like JavaScript).
For the specific case of glam (or other math libraries), mint exists to address this problem. Crates which want to be more stable than their algebra crate of choice can define their interface in terms of mint's types. For nearly the same ergonomics, define your function inputs as generic, taking impl IntoMint
(and probably monomorphize the actual impl to the specific type, if that would make it non-generic).
The tradeoff is that mint provides no functionality on its types, just structure; if you're going to work with the types directly, it needs to be via functions, not methods or (upstream) traits. (But hey, if you're using something like glm in C++, using functions for most things is standard practice anyway.) This is because despite algebra being fairly fundamental and stable[^1], the best API vocabulary for working with algebraic types in Rust is not.
And FWIW, it's not really any better in other languages' ecosystems. While you may have major algebra libraries that have been around and stable longer than the Rust gamedev scene has existed (e.g. glm in C++), it's extremely common for libraries/engines/etc to define their own types (especially in C++).
If you're a library for use with bevy, you use the bevy_math types, and if you don't update when bevy_math updates, you become legacy and lose users. Same for glam, nalgebra, or any other upstream; you either track upstream or get left behind. When you decided to publish your code for that ecosystem you took on that responsibility.
Yeah, if a crate has upwards of 1,000,000 downloads, it's probably time to be discussing what's required to be confident in committing to a 1.0 release, or at least pulling out a "lib-core" which can be 1.0. (Requiring less stable things to be defined in extension traits is unfortunate, though; I do hope we can eventually gain the ability to have "friend" crates, unstable crate APIs, or similar to ease this a bit.) By the original semver specification, if you're concerned about stability/backwards-compatibility and choosing not to make changes because they would cause breakage, it makes sense to claim that by having version 1.0.
Culturally, though, there's significant pressure that 1.0 is stable stable, and that there won't be a need for a 2.0. That you're even asking for crates to "be 1.0" illustrates this. What you actually want is that implied promise of longer-term stability.
Perhaps what's needed is tooling around "partially compatible" API revisions. This can't fix unmaintained dependencies not updating, but it could potentially be used as a lightweight way to patch them into using a later version where the API subset they actually utilize is compatible. (This is kinda possible already, but requires making a local version of the crate to patch with, utilizing the semver trick and reexporting the later version. It also only works for apps, not for publishing a library, but also, maybe upgrade your libraries off of unmaintained deps. If it's unmaintained, you forking it and only maintaining it enough to update public deps for your own usage is an improvement over the status quo, and relatively low effort.)
So yes, there's significant value to vocabulary crates getting to a properly stable 1.Y release. But it's not worth anything without the "properly." And it's also more difficult for non-std crates to do the whole "stability without stagnation" thing, because there's no standard way to handle experimental/unstable API additions. So, in short, it's complicated.
If a crate isn't 1.0 and you think it should be,
- Check their issue tracker to see if there's an issue/project/similar tracking what's desired before 1.0 (or even just for the next breaking release). If they're at the point of "should be 1.0," this should probably be publicly tracked, and if it isn't, asking about tracking it probably isn't completely unwarranted.
- The library maintainers' idea of what constitutes a 1.0 release probably disagrees with yours. You may be fine with a 1 year stability commitment; they may want a 5 year commitment, or even want an "essentially finished" level. Asking about and tracking what's desired for 1.0 will help clarify what the library is looking for.