Modern Swift bindings for libevent β a type-safe Swift 6.1 async/await API over kqueue on Apple platforms and epoll on Linux, plus a raw libevent product other Swift packages can link when they need libevent primitives directly.
π Documentation
Caution
Pre-1.0 and no version tag has been published yet. Version-based dependencies will be available after the first release; until then, use branch: "main". See the Production Considerations guide for the concurrency model, resource-ownership rules, and the list of capabilities not yet shipping.
Event is a thin, libevent-direct, async/await wrapper. It is not a replacement for SwiftNIO β reach for NIO when you need channel pipelines, HTTP/2 / WebSocket / TLS out of the box, or back-pressure-aware protocol handlers. Reach for Event when you want minimal abstraction over the platform I/O multiplexer, a small dependency surface, or tight interop with C code that already speaks libevent. For packages like swift-tor that embed C code calling event_base_* / evbuffer_* symbols, the raw libevent product provides a statically linked, vendor-controlled runtime.
- Async TCP client and server with
async/await:Socket.connect,Socket.listen,ServerSocket.connections(AsyncThrowingStream). - Platform-optimal multiplexer β
kqueueon Apple platforms,epollon Linux β verified at runtime and enforced by theEventLoop uses optimal backendtest. - libevent 2.1.12 statically vendored via subtree β no system libevent dependency at runtime.
- Raw
libeventC binding product for Swift packages that need libevent's full surface β used by swift-tor for its Tor daemon. - Swift 6.1 strict concurrency, documented single-owner handoff invariant, zero raw
OpaquePointerleakage in the public API.
Add the package to your Package.swift:
.package(url: "https://github.com/21-DOT-DEV/swift-event.git", branch: "main"),Warning
Pin branch: "main" until the first version tag ships (SemVer major version zero reserves this range as "anything may change at any time"). After 0.1.0, pin with exact: instead.
Include Event in your target:
.target(name: "<target>", dependencies: [
.product(name: "Event", package: "swift-event"),
]),Or use Xcode: File β Add Packagesβ¦, then enter https://github.com/21-DOT-DEV/swift-event.
import Event
let loop = EventLoop()
print(loop.backendMethod)
// kqueue (on macOS / iOS / tvOS / watchOS / visionOS)
// epoll (on Linux)β Full API: docs.21.dev/documentation/event/eventloop
For TCP client and server walkthroughs, IPv6 addresses, and the product-selection guide (Event vs libevent), explore the hosted documentation:
- Getting Started β task-oriented walkthrough of every shipping capability
- Backend & Platforms β the
kqueue/epollstory and the runtime invariant that enforces it - Production Considerations β pre-1.0 caveats, concurrency model, capabilities not yet shipping
Every example in the DocC catalog under Sources/Event/Event.docc/ is backed by an executable SwiftPM snippet, so nothing drifts from the code. Build the full hyperlinked archive locally with swift package generate-documentation --target Event.
| Tool | Minimum version |
|---|---|
| Swift | 6.1 |
| Xcode | 16.3 |
| macOS | 13 |
| iOS / iPadOS | 16 |
| tvOS | 16 |
| watchOS | 9 |
| visionOS | 1 |
| Linux | Ubuntu 22.04+ (glibc) |
Bug reports and pull requests are welcome. Start with:
- AGENTS.md β project architecture, Swift-target boundaries, extraction flow.
- Vendor/AGENTS.md β libevent subtree sync rules.
- 21-DOT-DEV contributing guidelines β branching and commit conventions.
For vulnerability reports, follow the private-disclosure process in the 21-DOT-DEV SECURITY.md. For shipped-today caveats β concurrency model, pre-1.0 SemVer status, and the list of capabilities not yet wrapped (TLS, UDP, timeouts, IPv6 server bind, cancellation) β see the Production Considerations guide.
Released under the MIT License β see LICENSE. libevent itself is licensed under the 3-clause BSD License.