Dependency injection for Swift
Make the graph explicit.
Skein registers the services your app owns, resolves them by type, and keeps UI-oriented graphs on MainActor by default.
Dependency injection for Swift
Skein registers the services your app owns, resolves them by type, and keeps UI-oriented graphs on MainActor by default.
import Skein
let appModule = module {
single((any HTTPClient).self, provider: { _ in URLSessionClient() })
factory(UserService.self, using: UserService.init)
}
try startSkein { appModule }
let service: UserService = try get()
stopSkein()Register values as lazy singletons, factories, and typed scopes. Use constructor injection, assisted factories, protocol bindings, qualifiers, and modules that compose by feature.
Skein uses Swift 6 and supports macOS 15, iOS 17, tvOS 17, watchOS 10, and visionOS 1. The optional Vapor integration also supports Linux.
The package, DocC articles, and executable examples are kept in the open repository. Stable releases include matching DocC archives.
Inspect the source ↗Registration has consequences
A single is lazy and cached after it resolves successfully. A factory runs every time. Constructor registrations record their dependencies, which lets Skein inspect declared roots before startup.
single
The provider runs on the first successful resolution. Later lookups return that value.
factory
The provider runs for every resolution. Its dependencies may still be singletons.
Latest stable release
Published August 15, 2026
Use this version when adding Skein with Swift Package Manager.
.package(url: "https://github.com/modern-swift-dev/skein-swift.git", from: "1.0.1")Skein 1.0.1 fixes Swift 6 compatibility issues affecting Linux builds and tests. ## Fixes - Work around Swift 6 pack-argument isolation diagnostics in constructor registration. - Update async XCTest setup, teardown, and expectation handling for Linux compatibility. Validated on Linux with Swift 6.0 and Swift 6.3, plus all supported Apple platform builds.
Read release notes ↗Built around Swift isolation
Unprefixed APIs keep UI graphs concise. Use the nonisolated... APIs for Sendable dependencies outside MainActor, or the async actor... APIs for your own global actor.