swift-libp2p

0.5.0

Modern libp2p networking stack for Swift
1amageek/swift-libp2p

What's New

swift-libp2p 0.5.0

2026-08-14T11:29:43Z
  • Complete the public Pure Swift networking dependency graph through swift-networking, swift-ssl, swift-tls, and swift-quic.
  • Accept coalesced QUIC Initial and Handshake server flights with independent outbound and receive UDP budgets.
  • Preserve underlying QUIC handshake failures and validate the receive-budget contract.
  • Verify Linux, macOS, Standard/Embedded WebAssembly runtime, and Go/Rust libp2p interoperability release gates.

swift-libp2p

A modern Swift implementation of the libp2p networking stack with wire-protocol compatibility with Go and Rust implementations. Built on Swift Concurrency (async/await, actors) for safe, high-performance peer-to-peer networking. The release line includes the Embedded-first LibP2PNode data path and the host P2P / Swarm stack.

Release status. Current release: 0.5.0.

Secure-transport composition

swift-libp2p is the top-level consumer and composition owner. It selects transports, applies PeerID and libp2p certificate policy, and does not implement TLS/DTLS/QUIC cryptographic mechanisms.

Stream: swift-libp2p -> swift-tls / TLS -> swift-ssl
WebRTC: swift-libp2p -> swift-webrtc -> swift-tls / DTLS -> swift-ssl
QUIC:   swift-libp2p -> swift-quic -> swift-tls / QUICTLS -> swift-ssl

This is the implemented architecture. The transport completion gates are recorded below with their reproducible commands and result bundles. See the package responsibility guide for the responsibility matrix.

Completion validation (updated 2026-08-14)

The completed libp2p transport profile is validated as an end-to-end path, not only as a compile-time API check:

UDP socket
   ├─ QUIC/TLS 1.3 ── Go libp2p (Ping, Identify)
   │                └─ Rust libp2p (Ping, Identify)
   ├─ WebRTC ICE ─ DTLS/SCTP ─ Noise ─ muxed libp2p stream
   │                ├─ Go libp2p Direct interop (Ping, Identify)
   │                └─ TURN relay ─ Pion private WebRTC (Ping)
Completion gate Evidence Status
Node and copy-contract correctness .test-artifacts/live-network/20260808T163241Z-68162 (65/65)
Real UDP QUIC .test-artifacts/live-network/post-fix-20260813 (localhost UDP, 1/1) and .test-artifacts/interop/20260814T095744Z (Go/Rust Ping, 2/2, no skips)
WebRTC Direct local UDP path .test-artifacts/interop/20260808T163623Z (Swift ↔ Go libp2p bidirectional stream, 1/1)
WebRTC Direct external interop .test-artifacts/interop/20260808T163623Z (Go libp2p, 1/1)
Private WebRTC through TURN .test-artifacts/interop/20260808T163623Z (Go Circuit Relay + Pion TURN/DTLS/SCTP + libp2p Ping, 1/1)
Pure Swift WSS .test-artifacts/interop/20260808T163623Z (Go ↔ Swift, 4/4)
WASM and Embedded WASM runtime .test-artifacts/portable-runtime/post-tls-half-close-20260813 (post-fix libp2p node and WebRTC on WASM and Embedded WASM; compile + link + runtime, 4/4)

Features

Transport

TCP (SwiftNIO), QUIC (RFC 9000), WebSocket, WebRTC Direct (DTLS + SCTP), Memory (testing)

Security

Noise XX (X25519 + ChaChaPoly + SHA256), TLS 1.3, Private Network (PSK + XSalsa20), Plaintext (testing)

Multiplexing

Yamux (flow control, keep-alive), Mplex, QUIC/SCTP native multiplexing

Discovery

SWIM membership, mDNS, CYCLON random sampling, Plumtree gossip, Beacon (BLE/WiFi/LoRa proximity)

Protocols

Identify, Ping, GossipSub v1.1/v1.2, Kademlia DHT (S/Kademlia), Plumtree, Circuit Relay v2, AutoNAT, DCUtR, Rendezvous, HTTP

NAT Traversal

Traversal Coordinator (local direct -> direct IP -> hole punch -> relay fallback), UPnP + NAT-PMP

Security Posture

  • Resource limits are enforced by default: NodeConfiguration.resourceManager is non-optional and defaults to an enforcing DefaultResourceManager (per-protocol/peer/connection limits). There is no silent "unlimited" default; opting out requires an explicit NullResourceManager().
  • Plaintext security is not @_exported from the P2P umbrella module (import P2PSecurityPlaintext explicitly). Production validation rejects plaintext and a disabled resource manager as errors.
  • PSK private networks (Pnet) are wired into both dial and listen and fail closed when a configured PSK cannot be applied.
  • GossipSub validates messages before inserting into the seen-cache, verifies signed peer-exchange records, and bounds control traffic (IHAVE/IWANT/GRAFT/PRUNE/IDONTWANT).
  • Kademlia's default validator verifies IPNS and public-key record signatures.
  • Identify verifies signed peer records when present; Circuit Relay, Rendezvous, and AutoNAT apply reservation/registration/rate limits.

Requirements

  • Swift 6.4 development snapshot swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-07-23-a
  • Matching WASM SDKs from the same snapshot
  • macOS 26+ / iOS 26+ / tvOS 26+ / watchOS 26+ / visionOS 26+

Installation

Add swift-libp2p to your Package.swift:

dependencies: [
    .package(url: "https://github.com/1amageek/swift-libp2p.git", from: "0.5.0")
]

P2P module re-exports common dependencies (batteries-included):

.target(
    name: "YourApp",
    dependencies: [
        .product(name: "P2P", package: "swift-libp2p")
    ]
)

Or pick individual modules:

.target(name: "YourApp", dependencies: [
    .product(name: "P2PCore", package: "swift-libp2p"),
    .product(name: "P2PTransportTCP", package: "swift-libp2p"),
    .product(name: "P2PSecurityNoise", package: "swift-libp2p"),
    .product(name: "P2PMuxYamux", package: "swift-libp2p"),
    .product(name: "P2PProtocols", package: "swift-libp2p")
])

Quick Start

import P2P

let node = Node(configuration: NodeConfiguration(
    keyPair: .generateEd25519(),
    listenAddresses: [Multiaddr("/ip4/0.0.0.0/tcp/4001")!],
    byteTransports: [TCPTransport()],
    security: [NoiseUpgrader()],
    muxers: [YamuxMuxer()]
))

try await node.start()
print("Listening as \(node.peerID)")

// Connect to a remote peer
let peer = try await node.connect(
    to: Multiaddr("/ip4/192.168.1.100/tcp/4001/p2p/12D3KooW...")!
)

// Open a stream
let stream = try await node.newStream(to: peer, protocol: "/chat/1.0.0")
try await stream.write(ByteBuffer(string: "Hello!"))

Products

The P2P umbrella re-exports the common batteries-included set; individual modules can also be imported directly.

Core

Module Description
P2PCore PeerID, Multiaddr, KeyPair, EventBroadcaster, Varint, Multihash
P2PNegotiation multistream-select v1 (+ 0-RTT lazy)
P2PNAT NAT device detection, UPnP + NAT-PMP port mapping
P2PRuntime runtime contracts such as ConnectionProvider and RuntimeConfiguration

Transport

Module Description
P2PTransport TransportAddressing, ByteTransport, and ByteListener contracts
P2PTransportTCP SwiftNIO-based TCP
P2PTransportQUIC QUIC (TLS 1.3, connection migration)
P2PTransportWebSocket WebSocket (HTTP/1.1 upgrade)
P2PTransportWebRTC WebRTC Direct (DTLS 1.2 + SCTP)
P2PTransportMemory In-memory transport for testing

Security

Module Description
P2PSecurity SecurityUpgrader, SecureChannel
P2PSecurityNoise Noise XX (X25519 + ChaChaPoly + SHA256)
P2PSecurityTLS TLS 1.3 with libp2p certificate extension
P2PPnet Private Network (PSK + XSalsa20, go-libp2p compatible). A configured PSK (NodeConfiguration(privateNetwork:)) is applied before security on both dial and listen, and fails closed if it cannot be applied (no unprotected fallback).
P2PSecurityPlaintext Plaintext (testing only)
P2PCertificate X.509 certificate generation/verification

Multiplexing

Module Description
P2PMux Muxer / StreamSession / StreamChannel protocols
P2PMuxYamux Yamux (256KB window, flow control, keep-alive)
P2PMuxMplex Mplex

Discovery

Module Description
P2PDiscovery discovery services, address books, peer stores, DiscoveryPipeline
P2PDiscoverySWIM SWIM membership (swift-SWIM integration)
P2PDiscoveryMDNS mDNS local network discovery
P2PDiscoveryCYCLON CYCLON random peer sampling
P2PDiscoveryPlumtree Plumtree gossip-based discovery
P2PDiscoveryBeacon BLE / WiFi / LoRa proximity discovery
P2PDiscoveryWiFiBeacon WiFi beacon adapter (UDP multicast)

Protocols

Module Description
P2PProtocols capability protocols, service roles, ServicePipeline
P2PIdentify Peer information exchange (+ Push)
P2PPing Connection liveness check
P2PGossipSub Pub/Sub messaging (v1.1 scoring + v1.2 IDONTWANT)
P2PKademlia DHT (S/Kademlia, latency tracking, persistent storage)
P2PPlumtree Epidemic Broadcast Trees
P2PCircuitRelay Relay v2 (client + server)
P2PAutoNAT NAT reachability detection
P2PDCUtR Direct Connection Upgrade through Relay
P2PRendezvous Namespace-based peer discovery
P2PHTTP HTTP semantics over libp2p

Integration

Module Description
P2PRuntime expert-facing runtime layer with ConnectionProvider and RuntimeConfiguration
P2P batteries-included facade with Node, NodeGroup, Service, Discovery, and the NodeGroupBuilder result builder

Architecture

The public surface is split into two layers: P2P (the batteries-included facade) and P2PRuntime (expert-facing runtime APIs). Runtime-facing connections are unified behind ConnectionProvider, service composition is explicit through ServicePipeline, discovery composition through DiscoveryPipeline, and payload paths are normalized on ByteBuffer.

Layer Stack

┌─────────────────────────────────────────────────────────────┐
│  Application                                                │
│  (GossipSub, Kademlia, your protocols)                      │
├─────────────────────────────────────────────────────────────┤
│  P2P facade                                                 │
│  Node / NodeGroup / NodeGroupBuilder(result builder)        │
├─────────────────────────────────────────────────────────────┤
│  P2PRuntime                                                 │
│  NodeRuntime / Swarm / ConnectionPool / Traversal           │
│  ServicePipeline / DiscoveryPipeline                        │
├─────────────────────────────────────────────────────────────┤
│  Runtime connection contract                                │
│  ConnectionProvider / ConnectionAcceptor / Candidate        │
├─────────────────────────────────────────────────────────────┤
│  Protocol Negotiation (multistream-select)                  │
├─────────────────────────────────────────────────────────────┤
│  Stream Multiplexing          Yamux, Mplex                  │
├─────────────────────────────────────────────────────────────┤
│  Security                     Noise, TLS 1.3, Pnet          │
├─────────────────────────────────────────────────────────────┤
│  Transport                TCP, QUIC, WebSocket, WebRTC      │
├─────────────────────────────────────────────────────────────┤
│  NAT Traversal  Circuit Relay v2, AutoNAT, DCUtR            │
├─────────────────────────────────────────────────────────────┤
│  Core           PeerID, Multiaddr, KeyPair, Events          │
└─────────────────────────────────────────────────────────────┘

Composition Model

  • Node is the facade composition root
  • NodeRuntime owns startup ordering, listeners, swarm startup, and discovery auto-connect
  • ServicePipeline resolves service components into lifecycle services, inbound handlers, peer observers, discovery sources, and listen-address contributors
  • Inbound streams capture one immutable protocol-route snapshot, so negotiation and dispatch always use the same handler generation while later registrations affect the next stream
  • DiscoveryPipeline owns child discovery services and their startup hooks

Data Plane

The payload path is designed around ByteBuffer.

  • transports, security wrappers, muxers, and stream I/O exchange ByteBuffer
  • control-plane codecs may still use Data
  • crypto and native adapter boundaries may still require Data
  • DataPathCopyGuardTests prevents new Data(buffer:) / ByteBuffer(bytes:) bridges from re-entering runtime-facing paths

This keeps hot-path payload movement on ByteBuffer while isolating unavoidable owned-byte conversions to explicit boundaries. The copy guard maintains an exact, stale-entry-detecting allowance ledger for plaintext and GossipSub protobuf decoding, the current swift-quic stream API, WebRTC signaling and datagrams, and legacy MplexFrame convenience APIs. Each allowance records why ownership must change and, for QUIC and GossipSub, has a dedicated release benchmark.

Event Delivery

Observational event streams use a required, bounded EventDeliveryPolicy; there is no unbounded mode. Every EventEmitting owner exposes cumulative EventDeliveryStatistics for attempted, enqueued, capacity-dropped, unobserved, and post-termination events. Events emitted before the single consumer obtains the stream are counted as unobserved rather than retained as hidden work.

Connection Flow

connect(to: Multiaddr)
  │
  ├─ Traversal Coordinator (stage-by-stage)
  │    ├─ 1. Local Direct (same LAN)
  │    ├─ 2. Direct IP
  │    ├─ 3. Hole Punch (AutoNAT + DCUtR)
  │    └─ 4. Relay (Circuit Relay v2)
  │
  ├─ ConnectionProvider.dial()
  │    ├─ transport -> security -> mux pipeline
  │    └─ or native secured provider (QUIC/WebRTC)
  │
  ├─ ConnectionPool.add()
  ├─ Swarm emits .peerConnected (fire-and-forget)
  ├─ Node event loop -> PeerObserver dispatch
  └─ Node emits NodeEvent.peerConnected

Configuration

Node Configuration

let node = Node(configuration: NodeConfiguration(
    keyPair: .generateEd25519(),
    listenAddresses: [Multiaddr("/ip4/0.0.0.0/tcp/4001")!],
    byteTransports: [TCPTransport()],
    security: [NoiseUpgrader()],
    muxers: [YamuxMuxer()],
    pool: PoolConfiguration(
        limits: .init(highWatermark: 100, lowWatermark: 80, maxConnectionsPerPeer: 2),
        reconnectionPolicy: .default,
        idleTimeout: .seconds(300)
    )
))

Services

Services are composed explicitly via ServicePipeline or Node { ... }:

let node = Node(
    keyPair: .generateEd25519(),
    listenAddresses: [Multiaddr("/ip4/0.0.0.0/tcp/4001")!],
    byteTransports: [TCPTransport()],
    security: [NoiseUpgrader()],
    muxers: [YamuxMuxer()]
) {
    GossipSub()
    Kademlia()
}

try await node.start()

Node.start() succeeds only after built-in discovery components have completed their startup hooks. A discovery startup failure is surfaced as a start error; it is not downgraded to a warning.

Production Profile

For a safer default operating profile, use .production:

let node = Node(
    profile: .production,
    keyPair: .generateEd25519(),
    listenAddresses: [Multiaddr("/ip4/0.0.0.0/tcp/4001")!],
    byteTransports: [TCPTransport()],
    security: [NoiseUpgrader()],
    muxers: [YamuxMuxer()]
) {
    Identify()
    GossipSub()
}

The production profile enables resource accounting and production-oriented pool and health-check defaults. Production validation reports an error (not a warning) for plaintext security and for a disabled resource manager.

NodeConfiguration.resourceManager is non-optional and defaults to an enforcing DefaultResourceManager. There is no silent "unlimited" default: per-protocol, per-peer, and per-connection limits are enforced. Opting out of limits requires an explicit NullResourceManager(), which production validation rejects as an error.

Plaintext security is not @_exported from the umbrella P2P module; callers that want it must import P2PSecurityPlaintext directly, and it is rejected by production validation.

You can also validate a node before startup:

do {
    try await node.start(validating: .production, behavior: .strict)
} catch let error as NodeStartValidationError {
    print("validation errors:", error.validation.errors)
    print("validation warnings:", error.validation.warnings)
}

The intended release path is:

  1. compose with Node(profile: .production) { ... }
  2. start with try await node.start(validating: .production, behavior: .strict)
  3. run scripts/production-gate.sh --include-benchmarks for the separate benchmark snapshot
  4. run the non-overridable scripts/release-gate.sh before shipping

Reusable groups can be modeled directly as NodeGroup values:

let chatStack = NodeGroup {
    Identify()
    GossipSub()
    MDNS()
}

let node = Node {
    chatStack
}

If you want a custom type, conform to NodeComponent and implement body declaratively:

struct MetricsStack: NodeComponent {
    let ping = PingService()

    var body: some NodeComponent {
        NodeGroup {
            Service(ping)
                .handlesInboundStreams()
        }
    }
}

Discovery with Auto-Connect

let node = Node(
    keyPair: .generateEd25519(),
    listenAddresses: [Multiaddr("/ip4/0.0.0.0/tcp/4001")!],
    byteTransports: [TCPTransport()],
    security: [NoiseUpgrader()],
    muxers: [YamuxMuxer()],
    discoveryConfig: .autoConnectEnabled
) {
    Identify()
    MDNS()
    SWIM()
}

Events

// Node events
Task {
    for await event in node.events {
        switch event {
        case .peerConnected(let peer):
            print("Connected: \(peer)")
        case .peerDisconnected(let peer):
            print("Disconnected: \(peer)")
        case .newListenAddr(let addr):
            print("Listening on: \(addr)")
        default: break
        }
    }
}

// Service events (e.g., GossipSub — EventBroadcaster, multi-consumer)
Task {
    for await event in gossipsub.events {
        switch event {
        case .messageReceived(let topic, let message):
            print("Message on \(topic): \(message.data)")
        default: break
        }
    }
}

Concurrency Model

Pattern When Examples
actor I/O heavy, user-facing API Node, Swarm, HealthMonitor
class + Mutex<T> High-frequency, sync access ConnectionPool, PeerStore
struct Data containers NodeConfiguration, SwarmEvent

Event Patterns

Pattern Consumers Examples
EventEmitting (single) One for await loop Ping, Identify, AutoNAT, Kademlia
EventBroadcaster (multi) Multiple independent loops GossipSub, SWIM, mDNS, Node

Wire Protocol Compatibility

Protocol Protocol ID Specification
multistream-select /multistream/1.0.0 spec
TLS 1.3 /tls/1.0.0 spec
Noise /noise spec
Yamux /yamux/1.0.0 spec
Mplex /mplex/6.7.0 spec
Identify /ipfs/id/1.0.0 spec
Ping /ipfs/ping/1.0.0 spec
Circuit Relay v2 /libp2p/circuit/relay/0.2.0/hop spec
GossipSub /meshsub/1.1.0 spec
Kademlia /ipfs/kad/1.0.0 spec
AutoNAT /libp2p/autonat/1.0.0 spec
DCUtR /libp2p/dcutr spec
Plumtree /plumtree/1.0.0 paper
CYCLON /cyclon/1.0.0 paper
WebRTC Direct /webrtc-direct spec

Performance

Hot paths are optimized to avoid heap churn and super-linear work: Base58 decode and Multiaddr.bytes are O(n); Kademlia closestPeers uses partial sort + bucket-proximity expansion; the GossipSub message cache and SWIM/Discovery peer stores use O(1) indexed/LRU structures; Noise HKDF avoids intermediate Data allocations; Yamux/Mplex read/write paths use offset tracking instead of repeated slice copies.

Current end-to-end release-build snapshot measured on 2026-08-13 with an Apple M4 Max, macOS 27.0, and Swift swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-07-23-a (ef761e567dc94ee):

Benchmark Result
Memory + Plaintext + Yamux connect 97,744.08 ns/op
Memory + Noise + Yamux connect 373,644.75 ns/op
Memory + TLS + Yamux connect 12,598,805.08 ns/op
Memory + Plaintext + Yamux roundtrip 1KB 10.43 MiB/s
Memory + Noise + Yamux roundtrip 1KB 19.50 MiB/s
Memory + TLS + Yamux roundtrip 1KB 21.86 MiB/s
Memory + Noise + Yamux roundtrip 32KB 69.56 MiB/s

The measured ownership boundaries are below. They remain below the end-to-end data path costs, so changing the public swift-quic ownership contract is not justified by the current profile.

Ownership boundary Result
QUIC [UInt8] -> ByteBuffer, 1KB 67.69 ns/op (14,426.81 MiB/s)
QUIC ByteBuffer -> [UInt8], 1KB 51.14 ns/op (19,097.57 MiB/s)
QUIC [UInt8] -> ByteBuffer, 64KB 719.43 ns/op (86,874.43 MiB/s)
QUIC ByteBuffer -> [UInt8], 64KB 715.43 ns/op (87,359.65 MiB/s)

The dedicated Noise comparison snapshot from 2026-08-07 measures real XX handshakes over paired in-memory transports and validates encrypted 1 MiB transfers. On an Apple M4 Max running macOS 27.0, with Swift swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-07-23-a, Rust 1.92.0, Go 1.26.5, libp2p-noise 0.46.1, and go-libp2p 0.49.0, 20 rotated-order release rounds produced:

Implementation Reconnect handshake, median (IQR) Established 1 MiB transfer, median (IQR)
Swift 148.54 µs (148.06–148.98) 1,603.80 MiB/s (1,599.81–1,618.83)
Rust libp2p 260.77 µs (260.62–260.95) 837.68 MiB/s (836.63–839.28)
Go libp2p 552.33 µs (551.24–553.61) 862.22 MiB/s (860.82–863.74)

Swift won all 20 rounds against both implementations: the paired median was 1.75x faster than Rust and 3.72x faster than Go for reconnect handshakes, and 1.91x / 1.86x faster for established transfer. Reconnect measurements reuse an unchanged peer identity and Noise static-key binding; a new or changed binding always performs signature verification before it can enter the bounded authentication cache.

The comparison is opt-in and separate from correctness tests. It builds all three pinned Release comparators, rotates implementation order, alternates operation order, and emits the raw samples as JSON:

SWIFT_TOOLCHAIN=org.swift.64202607231a \
  scripts/compare-noise-performance.py

Run the benchmarks via the production-readiness gate:

scripts/production-gate.sh
scripts/production-gate.sh --include-benchmarks

The production gate runs the runtime-facing copy guard, the public Node DSL tests, and the Node end-to-end suite through xcodebuild, then the opt-in live localhost network lane and the fixed interop release lane. The interop lane builds every required external image, executes Go/Rust QUIC, WSS, and WebRTC Direct/private, and rejects empty or skipped xcresult output. With --include-benchmarks it also runs the release benchmark snapshot for DataPathBenchmarks, GossipSubWireBenchmarks, NoiseCryptoBenchmarks, and QUICByteBoundaryBenchmarks.

The publication decision uses the fixed gate and accepts no skip or filter options:

scripts/release-gate.sh

It rejects local package dependencies, incomplete production markers, BoringSSL or NIOSSL references, noncanonical crypto repositories, and versions below the Pure Swift release floors in both host and Embedded dependency graphs. It then runs the complete production gate and the two-lane libp2p WASM/Embedded WASM compile-link-runtime matrix. swift-webrtc owns and runs its separate portable DTLS-SRTP validation matrix. Benchmarks remain a separate snapshot and are not part of ordinary correctness tests.

Testing

# Build the host package
xcodebuild build \
  -scheme swift-libp2p-Package \
  -destination 'platform=macOS' \
  CODE_SIGNING_ALLOWED=NO

# Build the portable LibP2PNode data path for WASM
SWIFT_NETWORKING_WASM=1 swift build \
  --swift-sdk swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-07-23-a_wasm \
  --target LibP2PNode

# Build the same LibP2PNode API and synchronization contract for Embedded WASM
SWIFT_NETWORKING_EMBEDDED=1 swift build \
  --swift-sdk swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-07-23-a_wasm-embedded \
  --target LibP2PNode

# Run deterministic correctness tests through the timeout-enforced xcodebuild gate
scripts/production-gate.sh --skip-live-network --skip-interop

# Run one focused xcodebuild suite
scripts/live-network-test.sh \
  --timeout 60 \
  --build-timeout 120 \
  --filter P2PTests/NodeDSLTests

# Live localhost network tests are opt-in: TCP, UDP, QUIC, WebSocket, WebRTC, NAT, and discovery
scripts/live-network-test.sh

# Release interoperability gate; fixed selection, no skips, requires Docker
scripts/interop-test.sh release --timeout 1200 --build-timeout 1200

# Short Go/Rust QUIC feedback lane
scripts/interop-test.sh smoke

# Benchmarks are opt-in and kept out of ordinary `xcodebuild test`
scripts/run-benchmarks.sh --configuration release

Dependencies

Package Purpose
swift-nio Network I/O
swift-crypto Cryptographic primitives for Native, WASM, and Embedded
swift-certificates Pure Swift X.509 handling
swift-asn1 Pure Swift ASN.1 encoding
swift-log Logging
swift-tls Stream TLS, DTLS, and QUIC TLS session contracts over pure Swift swift-ssl
swift-quic QUIC (RFC 9000)
swift-webrtc WebRTC Direct

References

License

MIT License

Description

  • Swift Tools 6.2.0
View More Packages from this Author

Dependencies

Last updated: Sun Aug 23 2026 03:20:14 GMT-0900 (Hawaii-Aleutian Daylight Time)