Worth noting that you can have a Node-style single-threaded event loop in Tokio if you want to, using the local runtime. You'd use tokio::task::spawn_local instead of spawn; spawn_local has no Send bounds (i.e., the Rust compiler won't require you to make your code thread-safe).