Single-file memory layer for AI agents, sub mili-second RAG on Apple Silicon. Metal Optimized On-Device. No Server. No API. One File. Pure Swift
# Add to your Claude Code skills
git clone https://github.com/christopherkarani/WaxLast scanned: 5/7/2026
{
"issues": [],
"status": "PASSED",
"scannedAt": "2026-05-07T06:36:50.687Z",
"semgrepRan": false,
"npmAuditRan": true,
"pipAuditRan": true
}No comments yet. Be the first to share your thoughts!
Wax is a Swift-native memory engine for AI agents. It stores documents, embeddings, and structured knowledge in a single .wax file that lives entirely on your device.
No servers. No API keys. No Docker. Just one file you can AirDrop, sync, or back up like any other document.
import Wax
let memory = try await Memory(at: url)
try await memory.save("The user prefers dark mode and uses Vim keybindings.")
let results = try await memory.search("What editor does the user like?")
// → "The user prefers dark mode and uses Vim keybindings."
Wax meets you where you are. Pick the path that matches what you're building:
| 🛠️ Swift Developer | ⌨️ CLI Power User | 🤖 AI Agent Setup | |:--------------------|:------------------|:------------------| | You want: Embed memory in your iOS/macOS app or Swift tool. | You want: A command-line memory store you can script against. | You want: Your AI assistant (Claude Code, Cursor, etc.) to remember context across sessions. | | Get started: Swift Quick Start ↓ | Get started: CLI Quick Start ↓ | Get started: Agent Quick Start ↓ |
Swift Package Manager
// Package.swift
dependencies: [
.package(url: "https://github.com/christopherkarani/Wax.git", from: "0.1.8")
]
Or in Xcode: File → Add Package Dependencies → https://github.com/christopherkarani/Wax.git
import Foundation
import Wax
let url = URL.documentsDirectory.appending(path: "agent.wax")
// Open a memory store
let memory = try await Memory(at: url)
// Save something
try await memory.save("The user is building a habit tracker in SwiftUI.")
// Recall it later — works even if the app was killed
let results = try await memory.search("What is the user building?")
if let best = results.items.first {
print("Found: \(best.text)")
// → "Found: The user is building a habit tracker in SwiftUI."
}
try await memory.close()
import SwiftUI
import Wax
struct ContentView: View {
@State private var result = "Searching…"
var body: some View {
Text(result)
.task {
do {
let url = URL.documentsDirectory.appending(path: "agent.wax")
let memory = try await Memory(at: url)
try await memory.save("The user is building a habit tracker in SwiftUI.")
let context = try await memory.search("What is the user building?")
result = context.items.first?.text ?? "Nothing found"
try await memory.close()
} catch {
result = "Error: \(error.localizedDescription)"
}
}
}
}
import Foundation
import Wax
@main
struct AgentMemory {
static func main() async throws {
let url = URL.documentsDirectory.appending(path: "agent.wax")
let memory = try await Memory(at: url)
try await memory.save("The user is building a habit tracker in SwiftUI.")
let results = try await memory.search("What is the user building?")
if let best = results.items.first {
print("Found: \(best.text)")
}
try await memory.close()
}
}
Looking to store persistent facts and long-term reasoning? See Structured Memory.
# Build from source (requires Swift 6+)
git clone https://github.com/christopherkarani/Wax.git
cd Wax
swift build -c release
# The binary is now at .build/release/wax-cli
cp .build/release/wax-cli /usr/local/bin/
# Save a memory
wax-cli remember "An automobile needs periodic maintenance."
# Search it back
wax-cli search "car service" --mode hybrid --topK 3
# Simple text-only search (no setup required)
wax-cli search "car service" --mode text
For long-running sessions, start the daemon:
wax-cli daemon --store-path ~/.wax/memory.wax
Then send JSON-line commands:
{"id":"1","command":"remember","content":"An automobile needs periodic maintenance."}
{"id":"2","command":"search","query":"car service","mode":"hybrid","topK":3}
{"id":"3","command":"shutdown"}
[!NOTE] Vector search requires the embedder. If it's unavailable, hybrid/vector commands fail loudly instead of silently falling back to text-only mode.
Give your AI coding assistant (Claude Code, Cursor, Windsurf) a persistent memory that survives across sessions.
npx -y waxmcp@latest mcp install --scope user
This stages the Wax runtime locally and registers wax-mcp with your assistant. npx is only used for the one-time install.
# From within your project directory
claude install-skill https://github.com/christopherkarani/Wax/tree/main/Resources/skills/public/wax
This lets your assistant write correct Wax code without extra prompt scaffolding.
Use the Wax MCP server for persistent memory in this repo.
Workflow rules:
- At session start, call `handoff_latest` first to load prior context, then call `session_start` once and keep the returned `session_id`.
- Use `remember` to store decisions, discoveries, and short factual notes. If the memory is session-scoped, pass `session_id` as a top-level argument. Do not put `session_id` inside `metadata`.
- Use `recall` for assembled context and `search` for raw ranked hits.
- Prefer `mode: "hybrid"` when semantic retrieval helps. Use `mode: "text"` when I want a fast or deterministic lexical lookup.
- Do not manage `SESSION_STORE`, `--store-path`, or `flush` in normal agent flows. The broker owns long-term memory and virtual session stores.
- Use `handoff` near the end of the session with `content`, optional `project`, and `pending_tasks`, then call `session_end`.
- Use `corpus_search` only when you need cross-session retrieval across broker-managed session history with provenance metadata.
- Use structured memory tools (`entity_upsert`, `fact_assert`, `fact_retract`, `facts_query`, `entity_resolve`) for stable entities and facts, not transient debugging notes.
Behavior expectations:
- Read existing handoffs and recall results before asking me to restate prior context.
- Keep memory writes concise, factual, and scoped to the task.
- When a cross-session result looks relevant, cite the provenance metadata so we know which session store it came from.
For the full Claude Code setup flow, see Resources/docs/wax-mcp-setup.md.
| Feature | Wax | SQLite (FTS5) | Cloud Vector DBs | |:-----------------|:-----------------------|:-----------------------|:-----------------------| | Search | Hybrid (Text + Vector) | Text Only* | Vector Only* | | Latency | ~6ms (p95) | ~10ms (p95) | 150ms - 500ms+ | | Privacy | 100% Local | 100% Local | Cloud-hosted | | Setup | Zero Config | Low | Complex (API Keys) | | Architecture | Apple Silicon Native | Ge