apple/swift-async-algorithms
Async Algorithms for Swift
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2mo ago
- ✓32+ active contributors
- ✓Distributed ownership (top contributor 36% of recent commits)
Show 3 more →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/apple/swift-async-algorithms)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/apple/swift-async-algorithms on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: apple/swift-async-algorithms
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/apple/swift-async-algorithms shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 2mo ago
- 32+ active contributors
- Distributed ownership (top contributor 36% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live apple/swift-async-algorithms
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/apple/swift-async-algorithms.
What it runs against: a local clone of apple/swift-async-algorithms — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in apple/swift-async-algorithms | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 96 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of apple/swift-async-algorithms. If you don't
# have one yet, run these first:
#
# git clone https://github.com/apple/swift-async-algorithms.git
# cd swift-async-algorithms
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of apple/swift-async-algorithms and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "apple/swift-async-algorithms(\\.git)?\\b" \\
&& ok "origin remote is apple/swift-async-algorithms" \\
|| miss "origin remote is not apple/swift-async-algorithms (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "Sources/AsyncAlgorithms/AsyncAlgorithms.docc/AsyncAlgorithms.md" \\
&& ok "Sources/AsyncAlgorithms/AsyncAlgorithms.docc/AsyncAlgorithms.md" \\
|| miss "missing critical file: Sources/AsyncAlgorithms/AsyncAlgorithms.docc/AsyncAlgorithms.md"
test -f "Package.swift" \\
&& ok "Package.swift" \\
|| miss "missing critical file: Package.swift"
test -f "Sources/AsyncAlgorithms/Channels/AsyncChannel.swift" \\
&& ok "Sources/AsyncAlgorithms/Channels/AsyncChannel.swift" \\
|| miss "missing critical file: Sources/AsyncAlgorithms/Channels/AsyncChannel.swift"
test -f "Sources/AsyncAlgorithms/Buffer/AsyncBufferSequence.swift" \\
&& ok "Sources/AsyncAlgorithms/Buffer/AsyncBufferSequence.swift" \\
|| miss "missing critical file: Sources/AsyncAlgorithms/Buffer/AsyncBufferSequence.swift"
test -f "Sources/AsyncAlgorithms/CombineLatest/CombineLatestStateMachine.swift" \\
&& ok "Sources/AsyncAlgorithms/CombineLatest/CombineLatestStateMachine.swift" \\
|| miss "missing critical file: Sources/AsyncAlgorithms/CombineLatest/CombineLatestStateMachine.swift"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 96 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~66d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/apple/swift-async-algorithms"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Swift Async Algorithms is an open-source package providing composable asynchronous sequence operators (zip, merge, combineLatest, chain, etc.) and time-based algorithms (debounce, throttle, chunking, rate-limiting) built on Swift 5.5's async/await and AsyncSequence foundation. It solves the problem of processing 'values over time' in concurrent Swift code by offering well-tested, production-grade implementations of complex multi-sequence composition patterns. Single-package structure: Sources/AsyncAlgorithms/ contains operator implementations (AsyncAdjacentPairsSequence.swift pattern), comprehensive docc guides in AsyncAlgorithms.docc/Guides/, and Evolution/ directory houses formalized RFC documents. Minimal C++ (8774 bytes, likely helper utilities). Swift codebase (808KB) organized by operator with paired documentation and test coverage.
👥Who it's for
Swift app developers and systems programmers building concurrent applications that need to coordinate multiple asynchronous data streams (e.g., iOS/macOS developers combining network requests, sensor streams, or UI events; backend developers handling real-time data pipelines). Also contributes to the Swift open-source community through the Evolution process.
🌱Maturity & risk
Actively maintained by Apple (evidenced by the apple/ namespace and sophisticated CI pipeline in .github/workflows/pull_request.yml). The Evolution/ directory with 18+ formalized proposals (0001-zip.md through 0018-flatMapLatest.md) and comprehensive docc documentation indicate this is a mature, thoughtfully-designed library. Production-ready with strong governance and cross-version support (Package@swift-5.7.swift, Package@swift-5.8.swift variants).
Low risk: Apple-owned and actively developed with formal evolution process. Primary risk is Swift version coupling (requires 5.5+); watch for breaking changes during major Swift releases. The monolithic algorithm design means breaking one operator could ripple across dependent code. Recommend pinning minor version in production.
Active areas of work
Latest work includes advanced combinators like flatMapLatest (Evolution/0018), multi-producer channel support (Evolution/0016), and mapError operator (Evolution/0017). Documentation and guide expansion ongoing (Debounce.md, Effects.md, Lazy.md guides). Library actively solidifying async composition patterns ahead of potential standard library adoption.
🚀Get running
git clone https://github.com/apple/swift-async-algorithms.git
cd swift-async-algorithms
swift build
swift test
Requires Swift 5.7+ toolchain. Use swift package --version to verify.
Daily commands:
Development: swift build compiles the library. swift test runs test suite. For documentation: swift build -Xswiftc -D -Xswiftc DEBUG or read Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/ markdown directly. Integration: add to Package.swift as .package(url: "https://github.com/apple/swift-async-algorithms.git", from: "1.0.0").
🗺️Map of the codebase
Sources/AsyncAlgorithms/AsyncAlgorithms.docc/AsyncAlgorithms.md— Main documentation entry point defining the package's scope, capabilities, and public API surface for all async algorithms.Package.swift— Swift Package Manager manifest declaring dependencies, platform targets, and module structure that all contributors must understand.Sources/AsyncAlgorithms/Channels/AsyncChannel.swift— Core multi-producer/consumer communication primitive used extensively by higher-level algorithms for value coordination.Sources/AsyncAlgorithms/Buffer/AsyncBufferSequence.swift— Fundamental buffering abstraction providing bounded and unbounded memory management for async sequences across the package.Sources/AsyncAlgorithms/CombineLatest/CombineLatestStateMachine.swift— Exemplar of the state-machine pattern used throughout the codebase for coordinating multiple concurrent async sequences.Sources/AsyncAlgorithms/Locking.swift— Synchronization utilities providing thread-safe primitives essential for concurrent async operations across all stateful algorithms.Sources/AsyncAlgorithms/Dictionary.swift— Dictionary extension adding async iteration capabilities, foundational for collection-based async transformations.
🛠️How to make changes
Add a new time-based async algorithm (e.g., custom timer variant)
- Create a new sequence wrapper type in Sources/AsyncAlgorithms/ following the naming convention AsyncYourAlgorithmSequence.swift that conforms to AsyncSequence (
Sources/AsyncAlgorithms/AsyncTimerSequence.swift) - If the algorithm needs state coordination across multiple producers/consumers, create a matching state machine and storage pair following the pattern in Sources/AsyncAlgorithms/Debounce/DebounceStateMachine.swift and DebounceStorage.swift (
Sources/AsyncAlgorithms/Debounce/DebounceStateMachine.swift) - Implement AsyncIterator with next() that manages internal state and uses Locking.swift primitives (Actor or Lock) for thread-safe coordination (
Sources/AsyncAlgorithms/Locking.swift) - Add an extension method on AsyncSequence or specific input types in the same file to expose the algorithm as a readable fluent API (
Sources/AsyncAlgorithms/AsyncThrottleSequence.swift) - Create documentation in Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/YourAlgorithm.md following the structure of existing guides (e.g., Guides/Debounce.md) (
Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/Debounce.md)
Add support for combining N sequences (extending 2-sequence variants to 3+ variants)
- Create AsyncCombineLatest3Sequence.swift (or higher arity) mirroring the structure in Sources/AsyncAlgorithms/CombineLatest/AsyncCombineLatest2Sequence.swift with additional type parameters (
Sources/AsyncAlgorithms/CombineLatest/AsyncCombineLatest2Sequence.swift) - Extend the shared CombineLatestStateMachine.swift to handle the additional sequence by adding new state variants and transition logic (
Sources/AsyncAlgorithms/CombineLatest/CombineLatestStateMachine.swift) - Add a new overload of the public API method (e.g., combineLatest(::_:)) on AsyncSequence to match the new arity (
Sources/AsyncAlgorithms/CombineLatest/AsyncCombineLatest3Sequence.swift) - Add tests in Tests/AsyncAlgorithmsTests following the naming and pattern of existing combineLatest test files (not shown but inferred from presence of Evolution proposals) (
Evolution/0006-combineLatest.md)
Add a new buffering variant (bounded vs. unbounded with custom semantics)
- Create a new state machine in Sources/AsyncAlgorithms/Buffer/ (e.g., CustomBufferStateMachine.swift) that extends or parallels UnboundedBufferStateMachine.swift with your custom drop/retain logic (
Sources/AsyncAlgorithms/Buffer/UnboundedBufferStateMachine.swift) - Create a matching storage class in the Buffer/ directory (e.g., CustomBufferStorage.swift) following the pattern of UnboundedBufferStorage.swift (
Sources/AsyncAlgorithms/Buffer/UnboundedBufferStorage.swift) - Update Sources/AsyncAlgorithms/Buffer/AsyncBufferSequence.swift to conditionally use your new state machine via a new public initializer or configuration parameter (
Sources/AsyncAlgorithms/Buffer/AsyncBufferSequence.swift) - Add an extension method on AsyncSequence in the same file to expose your custom buffer as .buffer(strategy: .yourCustom) (
Sources/AsyncAlgorithms/Buffer/AsyncBufferSequence.swift)
Add a new sequence transformation (map variant, filter, etc.)
- Create a new AsyncYourTransformSequence.swift file in Sources/AsyncAlgorithms/ implementing AsyncSequence and AsyncIterator following the pattern of AsyncCompactedSequence.swift or AsyncRemoveDuplicatesSequence.swift (
Sources/AsyncAlgorithms/AsyncCompactedSequence.swift) - Add a public extension method on AsyncSequence or the input element type to expose the transformation as .yourTransform(...) (
Sources/AsyncAlgorithms/AsyncCompactedSequence.swift) - If the transformation requires error handling, use AsyncMapErrorSequence.swift as a model for how to propagate failures (
Sources/AsyncAlgorithms/AsyncMapErrorSequence.swift) - Document the new transformation in Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/ with a .md file explaining behavior, performance, and gotchas (
Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/Compacted.md)
🪤Traps & gotchas
Backpressure handling: Unlike Combine, AsyncSequence doesn't have built-in backpressure signaling — operators must carefully manage Task creation and cancellation (visible in merge/combineLatest implementations). Clock/Time precision: Time-based operators (debounce, throttle, rate-limits) depend on ContinuousClock availability and precision; test on actual target platforms. Sendability: Requires elements and operator state to be Sendable for safe concurrent access — missing annotations can cause runtime crashes with -strict-concurrency. Version coupling: Some operators only available on Swift 5.8+ due to language features (check Evolution/ docs for version annotations).
🏗️Architecture
💡Concepts to learn
- AsyncSequence Protocol — The foundational abstraction for all operators in this repo — understanding how to implement and compose AsyncSequence is essential for contributing any new operator
- Structured Concurrency & Task Groups — Multi-sequence operators (merge, zip, combineLatest) rely on Task.withTaskGroup() and cancellation propagation to safely coordinate concurrent async sequences
- Backpressure Management in Async Streams — Unlike Combine's publishers, AsyncSequence doesn't have built-in backpressure — operators must manually manage Task creation and memory to avoid unbounded buffering (visible in merge/chain implementations)
- Clock Abstraction & Time-Based Algorithms — Debounce, throttle, and rate-limiting operators depend on Swift's Clock protocol for testable, platform-agnostic time measurement (introduced in Swift 5.9)
- Actor Isolation & Sendability — Time-based operators and channels require careful Sendability annotations and potential actor isolation to prevent data races in concurrent contexts
- Iterator State Machines — Each AsyncSequence operator wraps a state machine that tracks position, buffering, and completion across multiple next() calls — understanding this pattern is key to implementing new operators correctly
- Debouncing & Throttling in Async Contexts — These time-based algorithms suppress or rate-limit event emission — critical for handling rapid event streams (UI interactions, sensor data) in async Swift applications
🔗Related repos
apple/swift-evolution— Parent governance repo where formal Swift Enhancement Proposals (including AsyncSequence SE-0298) and related async/await features originatereactivex/RxSwift— Reactive streams library offering similar composition operators (map, filter, zip, combineLatest) but using Observables instead of AsyncSequence — direct conceptual sibling with different concurrency modelpointfreeco/swift-composable-architecture— Ecosystem consumer: TCA uses AsyncAlgorithms operators for effect composition and time-based side effects in Redux-like state managementapple/swift— Core Swift compiler and standard library repo where AsyncSequence protocol, async/await, and structured concurrency are definedapple/swift-nio— Cross-platform async I/O library that complements AsyncAlgorithms for network/file stream composition in server-side Swift
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive test coverage for AsyncShareSequence
AsyncShareSequence is a critical algorithm for sharing async sequences across multiple consumers, but there are no visible test files in the repo structure. This is a complex concurrent primitive that needs extensive testing for edge cases like task cancellation, multiple concurrent consumers, and reference counting behavior. Adding Tests/AsyncAlgorithmsTests/AsyncShareSequenceTests.swift would ensure reliability.
- [ ] Create Tests/AsyncAlgorithmsTests/AsyncShareSequenceTests.swift
- [ ] Add tests for basic multi-consumer sharing scenarios
- [ ] Add tests for task cancellation of one consumer while others are active
- [ ] Add tests for memory cleanup and reference counting
- [ ] Add tests for error propagation from the source sequence
- [ ] Add tests for early termination scenarios
Add documentation guide and tests for AsyncChannelSequence
Evolution/0012-channel.md exists indicating a Channel type was approved, but no corresponding .md guide file appears in Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/. Additionally, this is a complex concurrent primitive (likely multi-producer capability) that needs both user documentation and comprehensive tests. The Evolution doc references 0016-multi-producer-single-consumer-channel.md suggesting recent evolution.
- [ ] Create Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/Channel.md with detailed usage examples
- [ ] Document send/receive semantics and backpressure behavior
- [ ] Create Tests/AsyncAlgorithmsTests/AsyncChannelSequenceTests.swift
- [ ] Add tests for multi-producer scenarios from Evolution/0016
- [ ] Add tests for backpressure and buffering behavior
- [ ] Add tests for producer/consumer lifecycle and cleanup
Add missing documentation guide for FlatMapLatest algorithm
Evolution/0018-flatMapLatest.md exists in the Evolution directory indicating this feature was approved, but there's no corresponding .md guide file in Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/. This is a commonly-used operator (similar to switchMap in Rx) that needs user-facing documentation. The existing guide structure shows this is the expected pattern for API education.
- [ ] Create Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/FlatMapLatest.md
- [ ] Document the cancellation semantics when a new inner sequence is requested
- [ ] Include practical examples comparing flatMapLatest vs flatMap behavior
- [ ] Explain use cases for UI updates and network requests
- [ ] Add code examples demonstrating task cancellation behavior
- [ ] Reference the Evolution proposal in the guide
🌿Good first issues
- Add comprehensive unit tests for AsyncAdjacentPairsSequence.swift covering edge cases (empty sequences, cancellation mid-iteration, backpressure scenarios) — look at tests/ for existing pattern templates
- Expand Effects.md guide with concrete async/await error-handling examples (currently incomplete; pairs with Evolution/0017-map-error.md)
- Document the Clock protocol integration and timestamp semantics for time-based operators (debounce, throttle, rate-limits) — currently scattered across individual guides
⭐Top contributors
Click to expand
Top contributors
- @FranzBusch — 36 commits
- @phausler — 28 commits
- @twittemb — 4 commits
- @MaxDesiatov — 3 commits
- @scottmarchant — 2 commits
📝Recent commits
Click to expand
Recent commits
9d349bc— Cleanup pass for flatMapLatest and housekeeping tasks around proposals (#403) (phausler)5043186— feat: Add AsyncSequence.flatMapLatest operator (#382) (peterfriese)2971dd5— Fix a data race error with the internalOptional.takeSending(#399) (FranzBusch)103f5e5— Fix swift tool version (#374) (FirstAM)b8006a9— Add support for FreeBSD (#375) (kkebo)2de5003— Fix unbufferedsharedeadlock (#387) (alessionossa)ba54024— docs: Update comments in Locking.swift to better clarify threading scenario for WASILibc. (#393) (scottmarchant)65ed068— mapError - transforming failures (#366) (phausler)d98a48b— feat: Add support for compiling to wasm when pthreads aren't available (#389) (scottmarchant)6c050d5— MakeMPSCAsyncChannelsource methodsnonisolated(nonsending)(#380) (FranzBusch)
🔒Security observations
The swift-async-algorithms repository demonstrates a strong security posture. This is an open-source Swift package focused on asynchronous sequence algorithms with no apparent injection risks, hardcoded secrets, or critical misconfigurations. The codebase follows Apple's security practices and Swift language safety features. Minor recommendations exist for dependency management and CI/CD pipeline hardening, but no active vulnerabilities were detected in the static analysis.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.