Declarative collection and content builders for Swift
Create arrays, dictionaries, sets, strings, and markdown with SwiftUI-like result builder syntax
swift-builders provides a comprehensive collection of Swift Result Builders that transform how you create and manipulate data structures. Using familiar SwiftUI-style syntax, build complex collections and content with type safety, performance optimization, and clean, readable code.
import ArrayBuilder
import DictionaryBuilder
import StringBuilder
import SetBuilder
// Build complex arrays declaratively
let menuItems = Array<String> {
"Home"
"About"
if user.isAuthenticated {
"Dashboard"
"Profile"
}
for feature in enabledFeatures {
feature.menuTitle
}
}
// Generate configuration strings
let config = String {
"# Server Configuration"
"Host: \(serverHost)"
"Port: \(serverPort)"
if sslEnabled {
"SSL: Enabled"
"Certificate: \(certPath)"
}
}
// Create unique collections
let permissions = Set<Permission> {
.read
.write
userRole.defaultPermissions
if user.isAdmin {
[.admin, .delete]
}
}
// Build type-safe dictionaries
let configuration = Dictionary<String, String> {
("host", serverHost)
("port", "\(serverPort)")
if sslEnabled {
("ssl", "true")
("cert_path", certPath)
}
existingConfig // merge another dictionary
}- SwiftUI-like patterns: Familiar syntax for Swift developers
- Readable code: Express intent clearly with minimal boilerplate
- Natural flow: Write code that reads like the data structure you're building
- Compile-time validation: Catch errors before runtime
- Generic support: Full type inference and safety across all builders
- IDE integration: Complete autocomplete and refactoring support
- Zero overhead: Compile-time transformations with no runtime cost
- Memory efficient: Optimized operations avoid unnecessary allocations
- Scalable: Tested with large datasets (1000+ elements)
- Complete API coverage: All Swift result builder methods implemented
- Comprehensive tests: 144 tests covering edge cases and real-world usage
- Battle tested: Used in production applications
- Swift 5.10+ (Full Swift 6.0 support)
Add swift-builders to your Swift package:
dependencies: [
.package(url: "https://github.com/coenttb/swift-builders.git", from: "0.0.1")
]For Xcode projects, add the package URL: https://github.com/coenttb/swift-builders
import ArrayBuilder
struct NavigationMenu {
let user: User
var items: [String] {
Array {
"Home"
"About"
if user.isAuthenticated {
"Dashboard"
"Settings"
}
if user.isAdmin {
"Admin Panel"
}
}
}
}
// Simple and clean
let menu = NavigationMenu(user: currentUser)
print(menu.items) // ["Home", "About", "Dashboard", "Settings"]Build arrays with SwiftUI-like syntax:
import ArrayBuilder
// Type-safe array construction
let items = Array<String> {
"Always included"
if condition { "Conditional item" }
for item in collection { item.name }
}
// Perfect for UI data sources
let tableRows = Array<TableRow> {
HeaderRow()
ContentRows(from: data)
if showFooter { FooterRow() }
}Generate strings with automatic formatting:
import StringBuilder
// Configuration files
let config = String {
"# Application Config"
"version: \(appVersion)"
if isProduction {
"environment: production"
"debug: false"
} else {
"environment: development"
"debug: true"
}
}
// Log messages
let logEntry = String {
"[\(timestamp)]"
"[\(level.uppercased())]"
message
if let error = error {
"Error: \(error.localizedDescription)"
}
}Create Markdown with intelligent formatting:
import MarkdownBuilder
// Standard formatting (single newlines)
let readme = String(markdown: {
"# Project Title"
"Brief description here"
for feature in features {
"- \(feature.name): \(feature.description)"
}
})
// Paragraph formatting (double newlines for sections)
let documentation = String(markdownWithParagraphs: {
"# Getting Started"
""
"This guide will help you get started."
""
"## Installation"
""
for step in installSteps {
"1. \(step)"
}
})Build dictionaries with type-safe key-value construction:
import DictionaryBuilder
// Configuration dictionaries
let serverConfig = Dictionary<String, String> {
("host", "localhost")
("port", "8080")
if enableSSL {
("ssl", "true")
("cert_path", "/path/to/cert.pem")
}
existingConfig // merge existing dictionary
}
// Using KeyValuePair for better readability
let apiConfig = Dictionary<String, Any> {
KeyValuePair("timeout", 30)
KeyValuePair("retries", 3)
KeyValuePair("base_url", baseURL)
if isDebugMode {
KeyValuePair("debug", true)
KeyValuePair("verbose", true)
}
}
// Dynamic configuration
let appSettings = Dictionary<String, String> {
("app_name", appName)
("version", appVersion)
for (key, value) in environmentVars {
(key.lowercased(), value)
}
if user.isPremium {
("tier", "premium")
("features", premiumFeatures.joined(separator: ","))
}
}Build sets with automatic deduplication:
import SetBuilder
// Permission systems
let userPermissions = Set<Permission> {
.read
.write
rolePermissions
if user.isAdmin {
[.admin, .delete, .create]
}
}
// Tag collections
let articleTags = Set<String> {
"swift"
"programming"
category.defaultTags
if article.isFeatured {
"featured"
}
}import ArrayBuilder
struct APIResponse {
let users: [User]
let includeInactive: Bool
var responseData: [UserData] {
Array {
// Always include active users
users.filter(\.isActive).map(\.data)
// Conditionally include inactive users
if includeInactive {
users.filter { !$0.isActive }.map(\.data)
}
// Add system users for admin responses
if currentUser.isAdmin {
SystemUser.all.map(\.data)
}
}
}
}import StringBuilder
import MarkdownBuilder
struct WelcomeEmail {
let user: User
let features: [Feature]
var subject: String {
String {
"Welcome to \(AppConfig.name),"
user.firstName
}
}
var body: String {
String(markdown: {
"# Welcome, \(user.firstName)!"
""
"Thank you for joining \(AppConfig.name). Here's what you can do:"
""
for feature in features {
"- **\(feature.name)**: \(feature.description)"
}
""
if user.isPremium {
"## Premium Features"
""
"As a premium member, you also have access to:"
for premium in PremiumFeature.allCases {
"- \(premium.displayName)"
}
}
})
}
}import SetBuilder
import ArrayBuilder
struct GameSession {
let players: [Player]
let gameMode: GameMode
var availablePowerUps: Set<PowerUp> {
Set {
// Base power-ups for all games
PowerUp.basic
// Mode-specific power-ups
gameMode.defaultPowerUps
// Player-unlocked power-ups
for player in players {
player.unlockedPowerUps
}
// Special event power-ups
if Event.current?.isActive == true {
Event.current!.specialPowerUps
}
}
}
}import ArrayBuilder
struct APIRouter {
let isProduction: Bool
let features: FeatureFlags
var routes: [Route] {
Array {
// Core API routes
Route.health
Route.auth
// Feature-gated routes
if features.userManagement {
Route.users
Route.profiles
}
if features.analytics {
Route.analytics
Route.metrics
}
// Development-only routes
if !isProduction {
Route.debug
Route.testData
}
// Admin routes
if features.adminPanel {
for adminRoute in AdminRoute.allCases {
adminRoute.route
}
}
}
}
}import DictionaryBuilder
struct ConfigurationManager {
let environment: Environment
let features: FeatureFlags
let secrets: SecretStore
var databaseConfig: [String: Any] {
Dictionary {
("host", environment.databaseHost)
("port", environment.databasePort)
("database", environment.databaseName)
// Environment-specific settings
if environment.isProduction {
("pool_size", 20)
("timeout", 30)
("ssl_mode", "require")
} else {
("pool_size", 5)
("timeout", 60)
("ssl_mode", "prefer")
}
// Feature flags
if features.enableReadReplicas {
("read_replica_host", environment.readReplicaHost)
("read_replica_port", environment.readReplicaPort)
}
// Conditional authentication
if let credentials = secrets.databaseCredentials {
("username", credentials.username)
("password", credentials.password)
}
// Merge existing configuration
environment.customDatabaseSettings
}
}
var redisConfig: [String: String] {
Dictionary {
("host", environment.redisHost)
("port", "\(environment.redisPort)")
if environment.isProduction {
("cluster_mode", "true")
("max_connections", "100")
}
// Add authentication if available
if let auth = secrets.redisAuth {
("password", auth)
}
// Environment-specific overrides
for (key, value) in environment.redisOverrides {
(key, value)
}
}
}
}swift-builders provides five specialized result builders:
swift-builders
โโโ ArrayBuilder โ Generic array construction
โโโ DictionaryBuilder โ Key-value pair construction
โโโ SetBuilder โ Unique element collections
โโโ StringBuilder โ Text content generation
โโโ MarkdownBuilder โ Documentation and markup
Each builder is optimized for its specific use case while maintaining consistent APIs.
swift-builders includes comprehensive test coverage with 112+ tests:
import Testing
import ArrayBuilder
@Suite("ArrayBuilder Tests")
struct ArrayBuilderTests {
@Test("Conditional arrays")
func conditionalArrays() {
let items = Array<String> {
"always"
if true { "conditional" }
for i in 1...3 { "item-\(i)" }
}
#expect(items.count == 5)
}
}Test Coverage:
- โ Basic functionality for all builders
- โ Control flow (conditionals, loops, optionals)
- โ Edge cases and error conditions
- โ Performance characteristics
- โ Real-world usage patterns
Run tests with:
swift testAll builders are optimized for production use with zero runtime overhead:
- ๐ Compile-time: All builder logic happens at compile time
- ๐พ Memory Efficient: Optimized operations avoid unnecessary allocations
- ๐ Scalable: Tested with large datasets (1000+ elements)
- โก Fast: Direct operations without intermediate transformations
Benchmark results show consistent performance regardless of collection size.
Comprehensive documentation is available:
- ๐ API Reference - Complete API documentation
- ๐๏ธ Builder Guides - Detailed examples for each builder
- ๐ฏ Best Practices - Production patterns and tips
- ๐งช Testing Examples - How to test builder-based code
- ๐ Issue Tracker - Report bugs or request features
- ๐ฌ Discussions - Ask questions and share ideas
- ๐ง Newsletter - Stay updated with new releases
- ๐ฆ X (Twitter) - Follow for updates
- ๐ผ LinkedIn - Connect professionally
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Add tests for your changes
- Ensure all tests pass (
swift test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the Apache License 2.0. See LICENSE for details.
- coenttb.com - Full website built using swift-builders
- Real-world usage patterns
- Production-ready architecture
- Performance optimizations
Made with โค๏ธ by Coen ten Thije Boonkkamp