Small async retry primitives for Swift with explicit attempts and terminal cancellation.
Features · Installation · Quick Start · When To Use · Good Fits · Weaker Fits · Runtime Semantics · Documentation · Testing
- async-first retry entry point with
Retry { ... } - explicit
.maxAttempts(_:)configuration - fixed delay support through
.delay(_:) - terminal cancellation that is not retried
- small surface area intended to grow in layers
The current public API is intentionally centered on:
Retry
Add ResilienceKit to your Swift Package Manager dependencies:
dependencies: [
.package(url: "https://github.com/AltiAntonov/ResilienceKit.git", from: "0.1.0")
]Then add the product to your target:
.target(
name: "YourApp",
dependencies: [
.product(name: "ResilienceKit", package: "ResilienceKit")
]
)import ResilienceKit
let value = try await Retry {
try await fetchProfile()
}
.maxAttempts(3)
.delay(.seconds(1))
.run()maxAttempts(_:) always means total executions, including the first call.
Use ResilienceKit when you want retry behavior to be explicit, readable, and reusable instead of re-implementing ad hoc retry loops around async work.
It is a strong fit when the first thing you need is a small retry primitive, not a full resilience framework.
- app and SDK code that wraps async network requests
- codebases that want one obvious retry call site instead of repeated
forloops - teams that want to add backoff and jitter later without changing the entry-point shape
- small packages or apps that want focused retry behavior without unrelated dependencies
- projects that need backoff, jitter, or retry predicates today
- systems that already require a broader resilience stack such as circuit breaking or rate limiting
- sync-only code paths
- packages that need broad platform coverage below iOS 17 or macOS 14 right now
.maxAttempts(_:)controls the total number of attempts, not retries-after-the-first- values below
1are clamped to1 .delay(_:)configures a fixed delay between failed attempts and defaults to.zero- the first attempt always starts immediately
- delay is applied only between eligible retries, never after the final failed attempt
CancellationErroris terminal and is rethrown without additional attempts- all non-cancellation thrown errors are retried until attempts are exhausted
Backoff, jitter, and retry predicates are intentionally deferred to later releases.
The package now includes a DocC catalog in Sources/ResilienceKit/ResilienceKit.docc.
Once Swift Package Index processes .spi.yml, hosted documentation should appear on the package page automatically.
The package uses Swift Testing.
Current coverage verifies:
- first-attempt success
- retry-until-success behavior
- fixed delay between failed attempts
- no trailing delay after the final failed attempt
- exact call count on persistent failure
- clamp behavior for invalid attempt counts
- terminal cancellation from both pre-cancelled tasks, thrown
CancellationError, and cancellation during delay