>I think this take is an extremely subjective take.

Okay fair but that's all takes on this site :)

Yes, vertexAttribPointer is a footgun (in my project I wrote an analyser to generate a compiler error when you write it down...) but luckily in modern OpenGL it doesn't matter because you have separated vertex format. The names are confusing because it's legacy shit but the functionality is there. It's very much not as clean as other APIs but it gets the job done.

If you stick to the modern versions (so bindVertexBuffer / vertexAttribFormat / VertexAttribBinding) and do one VAO per vertex format, it's quite nice. And just forbid using the old ones. ;)

More broadly, I admit it's a subjective thing but I find these issues much smaller than like, broader conceptual issues. You mix the function names up a few times then you learn not to do it. But when an API is just fundamentally unergonomic and inflexible, you can't really get past that. Maybe you get used to it after a while but the pain will always be there....