You could still do mostly non-harmful no-JS PoW captchas by making some sort of FOSS external generator executable. Of course, this would be annoying to an extent, require mult-tasking for the user everytime, or custom keybinds, etc.

You could make it less annoying by borrow from TeamSpeak and/or hCaptcha. On TS3, as a server admin, you could set a minimum [pow-style] security-level to prevent spam/flooding. If server had a higher than default number, clients were prompted to improve their security-level or disconnect. And alternatively, as a client, you could pre-emptively generate higher/highest security-level (up to "30"?) over night or whenever you had spare cycles.

You could borrow that concept to allow non-JS clients to generate extra-strong tokens to allow them to bypass the system entirely. Or combinee that concept with what hCaptcha does for their disabled users -- once you solve the special disability captcha [or in this case, generate a stronger token], rather than inflict extra pain on the users, you get granted ~20 tokens or so to allow you to avoid the normal captcha system for a decent period of time.

If you want to go the extra mile and account for no-cookie use in addition to no-JS, allow it to be sent in the auth header or something.

Anyway, I don't know how many things I've seen use the concept, but IMO, it's under-utilized.

As a kid, I was super into reverse engineering RuneScape and writing our own MMORPG servers based on the protocol. Most of us had no idea what we were doing or what the games industry was doing, and we were all mostly kids, so we all had to be our own developers, db admins, sys admins, etc, and DDoS mitigation was effectively non-existent until OVH democratized it (BlackLotus would charge like $550 a month for a mediocre dedicated server, Staminus was similar, AwkNet was cheaper but only did TCP so TeamSpeak etc was still vulnerable, etc - and god knows how much Akamai and similar would've wanted).

One of the billion issues people ran into often was just login flooding; if it was a new username, that'd mean forcing the server to go through the new account and serialization process, and if it were an existing account, it A. opened up bruteforcing but B. forced the server to, at the very least, do password hashing, possibly database queries, or commonly reading a character file from disk, etc.

Rate-limiting by IP isn't super effective, because proxies. Rate-limiting / straight-up banning certain ASNs worked better to deal with VPNs, but you can't exactly grind all of Comcast or Verizion to a halt without disrupting users. And rate-limiting the particular account sucks, because you run into situations where individual players get targeted and effectively locked out of their account because someone is griefing them.

Far more effective than anything else was the idea of just generating some sort of PoW token on login that took a bit of time for the client to generate but was quick for the server to verify. Significantly better was the idea of being able to scale the difficulty globally, per IP/block, and importantly per account -- nearly no difficulty if no flooding is occurring, ~1-3 second logins if a massive flood is ongoing, or a per-account ~1-10 second difficulty if someone is trying to bruteforce a particular account. Even if the latter is mildly annoying, it's better than being totally blocked from playing.

RuneScape itself implemented this a couple of years ago too, I believe. I haven't seen them actually do much with the difficulty factor yet but even their super naive simple version seems to have helped a ton.

[of course this doesn't fix the issue of giant IoT botnets and stuff, but most people didn't (don't?) actually bother -- it was almost always DDoS amplification for volume and one or two servers with proxies doing the layer-7 floods]