For teams that want to adopt GraphQL, I think those tools are pretty great (and I've sent customers to them). However, we know from our customers there's lots of teams who don't want the shift of GraphQL (which tends to lead to GraphQL everywhere), but still want API composition.
At a language-to-language feature level, there's some core differences:
GraphQL-without-resolvers still relies on imperative joins defined somewhere. AFAIK, Wundergraph pushes this to the query layer. GraphQL Mesh pushes this to .yaml files. This means that as the sources change, there's centralized config needs to be updated in lock-step, or things break. This means the API producer is now obligated to work closely with consumers to release changes.
TaxiQL infers join logic by introspecting the schemas. This is especially powerful where joins require hops across multiple sources (eg., Id resolution where services use different ID schemes). Because type metadata is embedded at the producer schemas, producers are free to make changes and the query layer adapts.
GraphQL promotes a single graph that everyone cherry-picks from.
TaxiQL lets query authors define their own data contract, and own data shapes. This moves transformation of code into the query layer, which we think is a better place for it.
GraphQL doesn't allow extensibility in the language. (We've seen others hack around this with framework-specific annotations, but that's always felt quite awkward).
TaxiQL supports extensibility, adding custom functionality into the query layer, and ships with a pretty rich stdlib for things like avg(), first(), last(), etc.