swift-sexp is a lightweight utility for building S-expression formatted output strings in Swift, plus a small toolkit of protocols for rendering recursive descriptions of Swift types.
swift-sexp is a cross-platform Swift package on Darwin platform and Linux. Requires Swift 6.1+ (tools version 6.1).
| Workflow | CI Status |
|---|---|
| macOS Unit Test | |
| Ubuntu 22.04 Unit Test |
The package exposes two library products:
SExpPrinter— A value type that incrementally builds S-expression output with proper nesting and indentation.SExpPrintable— A protocol that conforming types can adopt to provide S-expression descriptions viaCustomStringConvertible.
public protocol SExpPrintable: CustomStringConvertible {
var tag: String { get }
func print(into printer: inout SExpPrinter)
}CustomRecursiveStringConvertible— A protocol that produces a hierarchical XML-style description of a type's attributes and children. Companion enumDefaultDescriptionAttributenames common graphical attributes.NestedCustomStringConvertible— A protocol that produces a nested, brace-indented description usingMirrorby default, with hooks for custom prefixes/suffixes.
Enable the package trait OpenSwiftUI to activate an extra Color.Resolved.name extension backed by OpenSwiftUICore. On Apple platforms with SwiftUI 7.0+ (iOS/macOS 26+) the same extension is offered on Color.ResolvedHDR.
In your Package.swift file, add the following dependency to your dependencies argument:
.package(url: "https://github.com/OpenSwiftUIProject/swift-sexp.git", from: "0.1.0"),Then add the dependency to any targets you've declared in your manifest:
.target(
name: "MyTarget",
dependencies: [
.product(name: "SExpPrinter", package: "swift-sexp"),
.product(name: "SwiftDescription", package: "swift-sexp"),
]
),import SExpPrinter
var printer = SExpPrinter(tag: "root")
printer.push("child")
printer.print("value")
printer.pop()
let output = printer.end()
// (root
// (child
// value))Conform your types to SExpPrintable for automatic description:
struct MyNode: SExpPrintable {
var tag: String { "MyNode" }
func print(into printer: inout SExpPrinter) {
printer.print("key=value")
}
}
print(MyNode()) // (MyNode key=value)Vendored sources (SExpPrinter + SwiftDescription) are synced from
OpenSwiftUI and
OpenGestures. The
mapping and last-synced commits are tracked in UPSTREAM.md.
The re-sync procedure is described in CLAUDE.md (symlinked as
AGENT.md for Codex) — running it is a one-prompt operation for
any LLM agent.
See LICENSE file - MIT