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.

A small application module
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()

Capabilities

Register values as lazy singletons, factories, and typed scopes. Use constructor injection, assisted factories, protocol bindings, qualifiers, and modules that compose by feature.

Platform support

Skein uses Swift 6 and supports macOS 15, iOS 17, tvOS 17, watchOS 10, and visionOS 1. The optional Vapor integration also supports Linux.

Source and docs

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

Pick a lifetime where the dependency is declared.

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

get()one cached value

The provider runs on the first successful resolution. Later lookups return that value.

factory

get()new value

The provider runs for every resolution. Its dependencies may still be singletons.

Choose a lifetime at registration time. Skein keeps that decision visible in the module.

Latest stable release

Skein 1.0.1

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

MainActor first. Explicit when it is not.

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.

Read the module guides →