<!--
{
  "documentType" : "article",
  "framework" : "Event",
  "identifier" : "/documentation/Event/GettingStarted",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Getting Started with Event in Swift"
}
-->

# Getting Started with Event in Swift

A task-oriented walkthrough of the three shipping capabilities in `Event`: inspecting the I/O backend, writing an async TCP client, and writing an async TCP server.

## Overview

Each section below solves one concrete task. Every executable example comes from a file under `Snippets/` that compiles on every `swift build`, so the code you see here stays in lock-step with the public API.

### Adding Event to Your Project

Add `swift-event` as a Swift Package Manager dependency. Because the package is pre-1.0 and no version tag has been published yet, pin to the `main` branch:

```swift
// Package.swift
.package(url: "https://github.com/21-DOT-DEV/swift-event.git", branch: "main"),
```

```swift
// Target dependencies
.target(name: "<target>", dependencies: [
    .product(name: "Event", package: "swift-event"),
]),
```

Then `import Event` in any Swift file that needs it. For the raw `libevent` C binding product (used when linking libevent into another Swift package that exposes its own C sources), see [Choosing Between Event and libevent](/documentation/Event/ChoosingLibeventVsEvent). For production-readiness caveats before depending on the package, read [Production Considerations](/documentation/Event/ProductionConsiderations).

### Inspecting the Event-Loop Backend

Every [`EventLoop`](/documentation/Event/EventLoop) wraps a libevent `event_base` configured with the platform’s most efficient I/O multiplexer. [`backendMethod`](/documentation/Event/EventLoop/backendMethod) returns the canonical method name; swift-event’s own test suite asserts that this is `"kqueue"` on Apple platforms and `"epoll"` on Linux. See [Backend and Platforms](/documentation/Event/BackendAndPlatforms) for the per-platform story and the reasons other backends are excluded.

```swift

```

Most applications will use [`shared`](/documentation/Event/EventLoop/shared), a process-wide singleton, and never need to construct their own loop. Allocate a dedicated loop only when you need isolation — for example, in tests that must not contend with application traffic.

### Writing an Async TCP Client

[`Socket`](/documentation/Event/Socket) exposes an async TCP client via two factory methods: [`connect(to:port:loop:)`](/documentation/Event/Socket/connect(to:port:loop:)) for numeric IPv4 endpoints and [`connect(to:loop:)`](/documentation/Event/Socket/connect(to:loop:)) for pre-built [`SocketAddress`](/documentation/Event/SocketAddress) values (including IPv6). The returned `Socket` owns its file descriptor and is ready for [`read(maxBytes:)`](/documentation/Event/Socket/read(maxBytes:)) / [`write(_:)`](/documentation/Event/Socket/write(_:)) without additional setup.

```swift

```

The example above assumes a server is listening on `127.0.0.1:8080`. All four operations (`connect`, `write`, `read`, `close`) are `async throws`; errors surface through [`SocketError`](/documentation/Event/SocketError) with a raw errno payload you can pattern-match to distinguish transient failures from permanent ones.

### Writing an Async TCP Server

The server side exposes a [`ServerSocket`](/documentation/Event/ServerSocket) produced by [`listen(port:backlog:loop:)`](/documentation/Event/Socket/listen(port:backlog:loop:)). Accept connections one at a time with [`accept()`](/documentation/Event/ServerSocket/accept()), or iterate the [`connections`](/documentation/Event/ServerSocket/connections) async stream to service each client as it arrives.

```swift

```

The `connections` stream is the idiomatic entry point for long-running servers — it composes with Swift structured concurrency so you can dispatch each accepted client onto a child task. Cancellation of the outer task terminates the `for try await` loop but does not currently unregister the outstanding libevent accept callback; call [`close()`](/documentation/Event/ServerSocket/close()) or drop the last strong reference to the `ServerSocket` to fully tear the listener down. See [Production Considerations](/documentation/Event/ProductionConsiderations).

### Constructing Socket Addresses

[`SocketAddress`](/documentation/Event/SocketAddress) is a value-type wrapper over `sockaddr_storage`. Three factory methods cover the common cases:

- ``doc://Event/documentation/Event/SocketAddress/ipv4(_:port:)`` for numeric IPv4 endpoints.
- ``doc://Event/documentation/Event/SocketAddress/ipv6(_:port:)`` for IPv6 (including IPv4-mapped IPv6).
- ``doc://Event/documentation/Event/SocketAddress/anyIPv4(port:)`` for binding servers to `0.0.0.0` on any local interface.

```swift

```

Parsing uses `inet_pton(3)` under the hood, so **DNS names are not resolved** — pass a literal IP address. Invalid input surfaces as [`SocketError.invalidAddress(_:)`](/documentation/Event/SocketError/invalidAddress(_:)) with the original host string as the payload.

### When to Reach for Event Instead of SwiftNIO

`Event` is a thin, libevent-direct, async/await wrapper; [SwiftNIO](https://github.com/apple/swift-nio) is a complete event-loop stack with channel pipelines, protocol handlers, and an ecosystem of ready-made modules for HTTP/1, HTTP/2, WebSocket, and TLS. Use this decision table:

|Use case                                                  |Framework                            |
|----------------------------------------------------------|-------------------------------------|
|Minimal wrapper over `kqueue`/`epoll` with async/await    |`Event`                              |
|Plain TCP client or server in a small dependency footprint|`Event`                              |
|Interop with existing libevent-based C or C++ code        |`libevent` (this package)            |
|HTTP/1, HTTP/2, WebSocket, TLS out of the box             |SwiftNIO                             |
|Back-pressure-aware channel pipelines                     |SwiftNIO                             |
|UDP, Unix-domain sockets, raw sockets                     |SwiftNIO (swift-event TCP-only today)|

### Using swift-event as a Runtime Dependency

Other Swift packages can consume `libevent` from this package directly without going through the `Event` Swift API. The concrete example is [`swift-tor`](https://github.com/21-DOT-DEV/swift-tor), whose `libtor` target links both `libevent` and swift-openssl’s `libcrypto` / `libssl`:

```swift
// From swift-tor's Package.swift
dependencies: [
    .package(url: "https://github.com/21-DOT-DEV/swift-openssl.git", branch: "main"),
    .package(url: "https://github.com/21-DOT-DEV/swift-event.git", branch: "main"),
],
targets: [
    .target(
        name: "libtor",
        dependencies: [
            .product(name: "libcrypto", package: "swift-openssl"),
            .product(name: "libssl", package: "swift-openssl"),
            .product(name: "libevent", package: "swift-event"),
        ],
        // ...
    ),
],
```

This pattern is the intended way to bring libevent into a Swift package that has its own C sources without bundling a duplicate libevent build. See [Choosing Between Event and libevent](/documentation/Event/ChoosingLibeventVsEvent) for the full product-selection rationale.

### Next Steps

- <doc://Event/documentation/Event/BackendAndPlatforms> — the kqueue / epoll story, runtime invariant, and excluded backends.
- <doc://Event/documentation/Event/ProductionConsiderations> — pre-1.0 caveats, the honest concurrency model, resource-ownership rules, and behaviors not yet shipping.
- <doc://Event/documentation/Event/ChoosingLibeventVsEvent> — when to import the Swift API vs the raw C binding product.
- ``doc://Event/documentation/Event/SocketError`` — the single failure surface for every throwing call in the module.