21-dot-dev/swift-event
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.
Why swift-event?
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.
Features
- 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.
Installation
Add the package to your Package.swift:
.package(url: "https://github.com/21-DOT-DEV/swift-event.git", from: "0.2.1"),[!WARNING] Because the package is pre-1.0, prefer pinning with
exact:instead offrom:if you want to lock to a specific minor version (e.g.exact: "0.2.1").from:will accept any 0.x release ≥ 0.2.1, and 0.x releases may include breaking changes per SemVer 0.y.z semantics.
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.
Quick Start
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.
Requirements
| 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) |
Contributing
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.
Security
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.
License
Released under the MIT License — see LICENSE. libevent itself is licensed under the 3-clause BSD License.
Package Metadata
Repository: 21-dot-dev/swift-event
Default branch: main
README: README.md