I've found it more annoying to mess with the browser validation API and using setCustomValidity/reportValidity etc. than to just use other validation libs. Ideally I'd use whatever library I want and they would call setCustomValidity for me though.
Using the related pseudo classes :valid, :invalid, :required, :optional is nice, but until last year you still had to do custom logic there because :user-valid/:user-invalid weren't implemented outside of Firefox. That created additional work and was annoying.
Really? In my experience they easily cover the majority of cases - strings versus numbers, min and max length, upper and lower bounds to values, specifying what decimal level you’ll accept, you can even straight up provide a regex in the ‘pattern’ attribute.