It is not perfect yet, and especially how tokio does not follow the rest of the ecosystem by implementing their own traits is kind of disappointing. We can work around that, but I was hoping they would fix this by version 1.0...
Another way to be runtime agnostic is to start a particular runtime as part of your library, which is used internally. The public interface of your library can provide async functions which are agonstic to a particular runtime, since all actions will be deferred/forwarded to an internal runtime. That approach has a bit more overhead, but can ease usage.
I understand the reasoning for not wanting this in the core language, but perhaps there could be some standard implementations which would still allow for custom runtimes.