Introduction
libuv is a multi-platform C library that provides an event loop with async I/O, originally developed for Node.js. It abstracts OS-specific APIs (epoll, kqueue, IOCP, event ports) behind a single portable interface, enabling high-performance network servers and system tools on Linux, macOS, Windows, and more.
What libuv Does
- Manages an event loop with support for timers, idle watchers, and signal handlers
- Provides non-blocking TCP and UDP sockets with connection pooling
- Offers async file system operations backed by a thread pool
- Handles DNS resolution, child process spawning, and IPC via pipes
- Delivers cross-platform threading, mutexes, and read-write locks
Architecture Overview
At its core libuv runs a single-threaded event loop that polls for I/O readiness using the fastest OS primitive available. Network I/O is handled directly in the loop thread. File system operations and DNS lookups are dispatched to a configurable thread pool (default 4 threads) since most OSes lack true async file I/O. Callbacks fire on the loop thread, avoiding synchronization complexity for users.
Self-Hosting & Configuration
- Build with CMake:
mkdir build && cd build && cmake .. && make - Link against
libuv(shared) orlibuv_a(static) - Set the thread pool size via
UV_THREADPOOL_SIZEenvironment variable (default 4, max 1024) - Works on Linux, macOS, Windows, FreeBSD, Solaris, AIX, and Android
- Minimum requirement: C89 compiler; no C++ or external dependencies
Key Features
- Powers Node.js, Neovim, Julia, Luvit, and many other runtimes
- Full-featured IOCP support makes it one of the best async libraries on Windows
- Stable C API with strong backward compatibility guarantees
- Extensive test suite and continuous fuzzing via OSS-Fuzz
- MIT licensed with an active community and regular releases
Comparison with Similar Tools
- libevent — older, similar scope; libuv has simpler API and better Windows support
- libev — Unix-focused, no native Windows IOCP; lighter but less portable
- Boost.Asio — C++ only, header-heavy; libuv is plain C with smaller footprint
- io_uring — Linux-only kernel interface; libuv wraps it on newer kernels transparently
- mio (Rust) — similar abstraction but for Rust; libuv targets C/C++
FAQ
Q: Is libuv only for Node.js? A: No. It is a standalone C library used by Neovim, Julia, Luvit, CMake, and hundreds of other projects.
Q: Does libuv support io_uring? A: Experimental io_uring support was added for file I/O on Linux. Network I/O still uses epoll by default.
Q: How does the thread pool affect performance?
A: The pool handles blocking operations (file I/O, DNS). Increase UV_THREADPOOL_SIZE if your workload is file-heavy.
Q: Can I embed multiple event loops?
A: Yes. You can create multiple loops with uv_loop_new(), each running in its own thread.