swift-valkey/SKILL.md
Expert guidance on using Valkey and Redis with Swift. Use when developers mention: (1) Valkey or Redis in Swift, (2) valkey-swift library, (3) RESP protocol or RESP3, (4) Redis cluster routing or hash slots, (5) pub/sub or subscriptions, (6) Redis transactions or MULTI/EXEC, (7) caching with Redis.
npx skillsauth add wendylabsinc/claude-skills swift-valkeyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Valkey is an open-source, high-performance key-value store (fork of Redis). The valkey-swift library provides a Swift client with full async/await support, cluster routing, and pub/sub.
Add to Package.swift:
dependencies: [
.package(url: "https://github.com/valkey-io/valkey-swift.git", from: "1.0.0")
]
import Valkey
// Connect to single server
let client = try await ValkeyClient.connect(to: .init(host: "localhost", port: 6379))
// Basic operations
try await client.set("key", "value")
let value = try await client.get("key") // Optional<String>
// With expiration
try await client.set("session", sessionData, expiration: .seconds(3600))
// Delete
try await client.del("key")
// Connect to cluster
let client = try await ValkeyClient.connect(
to: .cluster([
.init(host: "node1.redis.local", port: 6379),
.init(host: "node2.redis.local", port: 6379),
.init(host: "node3.redis.local", port: 6379)
])
)
// Commands automatically route to correct shard
try await client.set("user:123", userData)
// SET with options
try await client.set("key", "value", condition: .nx) // Only if not exists
try await client.set("key", "value", condition: .xx) // Only if exists
try await client.set("key", "value", expiration: .milliseconds(5000))
// GET
let value = try await client.get("key")
// INCR/DECR
let newValue = try await client.incr("counter")
let decreased = try await client.decr("counter")
try await client.incrBy("counter", 10)
try await client.hset("user:123", field: "name", value: "Alice")
try await client.hset("user:123", fields: ["name": "Alice", "email": "[email protected]"])
let name = try await client.hget("user:123", field: "name")
let user = try await client.hgetall("user:123") // [String: String]
try await client.lpush("queue", "item1", "item2")
try await client.rpush("queue", "item3")
let item = try await client.lpop("queue")
let items = try await client.lrange("queue", start: 0, stop: -1)
try await client.sadd("tags", "swift", "redis", "backend")
let isMember = try await client.sismember("tags", "swift")
let members = try await client.smembers("tags")
try await client.zadd("leaderboard", score: 100, member: "player1")
try await client.zadd("leaderboard", members: [("player2", 200), ("player3", 150)])
let top10 = try await client.zrange("leaderboard", start: 0, stop: 9, withScores: true)
let rank = try await client.zrank("leaderboard", member: "player1")
// Subscribe to channels
let subscription = try await client.subscribe(to: ["notifications", "updates"])
// Process messages
for try await message in subscription {
switch message {
case .message(let channel, let payload):
print("Received on \(channel): \(payload)")
case .subscribe(let channel, let count):
print("Subscribed to \(channel)")
}
}
// Publish
try await client.publish("notifications", message: "Hello subscribers!")
// Pattern subscribe
let patternSub = try await client.psubscribe(to: ["user:*", "event:*"])
// MULTI/EXEC transaction
let results = try await client.transaction(
SET("key1", "value1"),
SET("key2", "value2"),
GET("key1")
)
// Results is tuple: (Result<String?, Error>, Result<String?, Error>, Result<String?, Error>)
// Execute multiple commands in single round-trip
let (setResult, getResult, incrResult) = try await client.execute(
SET("key", "value"),
GET("key"),
INCR("counter")
)
Commands are automatically routed to the correct shard based on key hash slots:
// Keys with same hash tag go to same shard
try await client.set("{user:123}:profile", profileData)
try await client.set("{user:123}:settings", settingsData)
// Both keys route to same shard due to {user:123} hash tag
let config = ValkeyClient.Configuration(
endpoints: .single(.init(host: "localhost", port: 6379)),
password: "secret",
database: 0,
connectionTimeout: .seconds(5),
commandTimeout: .seconds(30),
tls: .require(.makeClientConfiguration())
)
let client = try await ValkeyClient.connect(configuration: config)
do {
let value = try await client.get("key")
} catch let error as ValkeyClientError {
switch error {
case .connectionClosed:
// Reconnect logic
case .timeout:
// Retry logic
case .serverError(let message):
print("Server error: \(message)")
}
}
Load these files as needed for specific topics:
references/valkey-patterns.md - Command protocol pattern, RESP encoding/decoding, cluster routing with hash slots, subscription management, transaction patterns, connection pool integration, module extensionsdevelopment
Expert guidance on Swift best practices, patterns, and implementation. Use when developers mention: (1) Swift configuration or environment variables, (2) swift-log or logging patterns, (3) OpenTelemetry or swift-otel, (4) Swift Testing framework or @Test macro, (5) Foundation avoidance or cross-platform Swift, (6) platform-specific code organization, (7) Span or memory safety patterns, (8) non-copyable types (~Copyable), (9) API design patterns or access modifiers.
tools
Expert guidance on building and deploying apps to WendyOS edge devices. Use when developers mention: (1) Wendy or WendyOS, (2) wendy CLI commands, (3) wendy.json or entitlements, (4) deploying apps to edge devices, (5) remote debugging Swift on ARM64, (6) NVIDIA Jetson or Raspberry Pi apps, (7) cross-compiling Swift for ARM64.
development
Curated Swift package ecosystem for WendyOS and Linux. Use when developers mention: (1) Swift packages for Linux or ARM64/AMD64, (2) choosing a Swift library, (3) Swift Package Index, (4) swiftpackageindex.com, (5) what Swift library to use, (6) Swift on WendyOS dependencies, (7) edge computing Swift libraries.
development
Expert guidance on building WASM apps for Wendy Lite MCU firmware on ESP32-C6. Use when developers mention: (1) Wendy Lite or wendy-lite, (2) WASM apps on ESP32 or microcontrollers, (3) WendyLite Swift package or import WendyLite, (4) building C/Rust/Swift/Zig apps for ESP32, (5) WAMR runtime on embedded devices, (6) GPIO/I2C/SPI/UART/NeoPixel from WASM, (7) Embedded Swift on WASM or wasm32-none-none-wasm, (8) BLE provisioning on ESP32-C6, (9) uploading WASM binaries to MCU, (10) TLS/networking on ESP32 from Swift.