Or fish, which is basically zsh with sane defaults.

And a completely incompatible non-POSIX syntax, which sounds great in theory but isn't nearly enough better to justify the departure IMHO.

Why does compatibility matter? If you have a script written for sh or bash it will just run using that interpreter.

For starters, any utilities based on sourcing won't work, such as nvm/rbenv/etc.

That's technically true for zsh in cases, but it's far easier to port or add compatibility for zsh than fish.

You can use bass which solves this problem without porting the script to fish: https://github.com/edc/bass