Swift Signals

Warning This library is still under development and does not work yet.

Signals is a performant state management library with two primary goals:

  1. Make it as easy as possible to write business logic for small up to complex apps. No matter how complex your logic is, your app updates should stay fast without you needing to think about it. Signals automatically optimize state updates behind the scenes to trigger the fewest updates necessary. They are lazy by default and automatically skip signals that no one listens to.
  2. Integrate into frameworks as if they were native built-in primitives. You don’t need any selectors, wrapper functions, or anything else. Signals can be accessed directly and your views will automatically re-render when the signal’s value changes.

Guide / API

The signals library exposes two classes and a function which are the building blocks to model any business logic you can think of. These constructs are built on Swift’s @Observable macro and Observation runtime.

Signal<Wrapped>(_: Wrapped)

import SwiftSignals

let counter = Signal(0)

// Read value from signal, prints: 0
print(counter.value)

// Write to a signal
counter.value = 1

signal.peek()

let counter = Signal(0)
let effectCount = Signal(0)

effect {
    print(counter.value)

    // Whenever this effect is triggered, increase `effectCount`.
    // But we don't want this signal to react to `effectCount`
    effectCount.value = effectCount.peek() + 1
}

Computed<Wrapped>(_: () -> Wrapped)

import SwiftSignals

let name = Signal("Jane")
let surname = Signal("Doe")

let fullName = Computed {
    name.value + " " + surname.value
}

// Prints: "Jane Doe"
print(fullName.value)

// Updates flow through computed
name.value = "John"
// Prints: "John Doe"
print(fullName.value)

effect(_: () -> Void)

import SwiftSignals

let name = Signal("Jane")
let surname = Signal("Doe")

let fullName = Computed {
    name.value + " " + surname.value
}

// Prints: "Jane Doe"
effect {
    print(fullName.value)
}

// Updating one of its dependencies will automatically trigger
// the effect above, and will print "John Doe" to the terminal.
name.value = "John"

GitHub

View Github