Dependency-free, high-performance concurrent shell framework for Swift 6.0+
SwiftSlash 4.0 is a pure-Swift library (zero external dependencies) designed for rock-solid reliability and speed. Its internal engine ensures:
- 🔒 Memory Safety: Automatic cleanup of file descriptors and subprocesses guarantees no memory leaks or zombie processes.
- ⚡ Blazing Performance: Fast process startup, I/O streaming, and internal scheduling without per-process event loops.
- 🔄 True Concurrency: Run hundreds or thousands of shell commands in parallel, leveraging Swift’s async/await for minimal overhead.
- 🛡 Secure Execution: Isolated handles and controlled working-directory management ensure a hardened runtime.
- 📦 Type-Safe API: Leveraging Swift 6.0/6.1’s advanced type system for compile-time correctness and clear intent.
- 🛑 Native Task Cancellation: Cancelling the awaiting
Taskterminates the child process and, when its placement gives it one, its entire process group — then reaps all resources and surfacesCancellationError. No orphaned or zombie processes. - 🧬 Process-Group Control: Every launch decides where its child sits — its own process group, the launcher's group (so an outer teardown cascades through a nested launch), or a detached session that outlives it. A launch that runs inside another launch resolves this automatically, so grandchildren are never left running after the caller has given up.
Full DocC documentation is available at swiftslash.com/documentation.
Don't want SwiftSlash's built-in stdio pipeline for a given process? Hand it a file descriptor you already own — SwiftNIO, sockets, PTYs, or anything else — and SwiftSlash binds it to the child and stays out of the data path entirely. Reaping and cancellation remain fully intact.
import Foundation
import SwiftSlash
let pipe = Pipe()
let child = ChildProcess(
try Command("/bin/cat"),
dataChannels: [
STDIN_FILENO: .read(.byo(fd: .init(rawValue: pipe.fileHandleForReading.fileDescriptor))),
STDOUT_FILENO: .write(.byo(fd: .init(rawValue: pipe.fileHandleForWriting.fileDescriptor))),
STDERR_FILENO: .write(.byo(fd: .init(rawValue: pipe.fileHandleForWriting.fileDescriptor)))
]
)
async let exit = child.run()
// ... drive `pipe` with SwiftNIO (or anything else) — SwiftSlash never touches it.See the BYO Data Channels article for the full ownership contract.
We welcome bug reports, feature requests, and pull requests.
SwiftSlash is released under the MIT License. See LICENSE for details.
Stay up to date or ask questions on Twitter: @tannerdsilva