I think wsproto is a good example of what is possible. It’s just a state machine, bring your own networking. If you can contain the core logic to something usable by both a sync or async pipeline, maintaining both a sync and async user api is just wrapping the same core. It might still be useful to pair with codegen, but it might be easier to generate the sync and async paths if the core logic and state is decoupled.