libuv has provided an async interface for io using a worker thread pool for a decade, no dependency on io_uring required. I guess the threadpool they mention that aiofiles uses is written in python, so it gives concurrency but retains the GIL, so no parallelism. Node's libuv async stuff moves all the work off the main thread into c/c++ land until results are ready, only when dealing with the completed data read event does it re-enter the NodeJS "GIL" JavaScript thread.
To be clear: libuv has had the ability to offload (some?) I/O operators to io_uring since v1.45.0, from 2023, and that's the 8x speed improvement. 2024 is when node.js seemed to enable (or rather, stop disabling) io_uring by default in its own usage of libuv.
Yeah if you look at the libuv release history there’s been a lot of adding and subtracting since then. It’s clearly not all settled but there are chunks.