> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myme.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Install, three client modes, configuration

The Swift SDK is a Swift Package Manager library for Apple platforms. It exposes three client modes over the same API surface — a remote HTTP client, a pure-local on-device store, and a synced mode that queues writes locally and replays them against a server. Swift 6 concurrency throughout.

Repository: [`withmarfa/swift-sdk`](https://github.com/withmarfa/swift-sdk). Pin to the major version that tracks your server.

Platforms: iOS 26+, iPadOS 26+, macOS 26+, watchOS 26+, tvOS 26+, visionOS 26+. On-device storage uses SwiftData — no third-party runtime dependencies.

## Install

In `Package.swift`:

```swift theme={null}
dependencies: [
  .package(url: "https://github.com/withmarfa/swift-sdk.git", from: "x.y.z"),
]
```

Or in Xcode: **File → Add Package Dependencies → `https://github.com/withmarfa/swift-sdk.git`**.

## Three client modes

One SDK, three factories. Pick the one that matches your app:

<Tabs>
  <Tab title="Remote">
    A thin typed HTTP client. Every call hits the server.

    ```swift theme={null}
    import MarfaSDK

    let client = MarfaClient(
      url: URL(string: "https://marfa.example.com")!,
      apiKey: "marfa_k1_..."
    )

    let note = try await client.items.create(
      CreateItemInput(type: "core.note", properties: ["body": .string("Hello")])
    )
    ```

    Best for: server-first apps, scripts, CI, server-to-server integrations.
  </Tab>

  <Tab title="Pure-local">
    SwiftData-backed on-device store. No server, no API key. Same namespace surface — every call resolves against the local store.

    ```swift theme={null}
    let client = try await MarfaClient.local(path: "/path/to/store.sqlite")

    let note = try await client.items.create(
      CreateItemInput(type: "core.note", properties: ["body": .string("Offline")])
    )
    ```

    Best for: offline-first apps, privacy-first apps, prototyping before adding a server.

    <Info>
      Server-only namespaces — `blobs`, `types`, `keys`, `webhooks` — throw `LocalModeUnsupportedError` on a pure-local client. `client.blobs.url(hash:)` is the lone exception; it returns a constructed URL without touching the network.
    </Info>

    <Note>
      For iCloud sync, build the container yourself with `MarfaModelContainer.make(path:cloudKitDatabase: .automatic(containerIdentifier: "iCloud.example.app"))` and pass it to `MarfaClient.local(container:)`. The schema is CloudKit-compatible from day one.
    </Note>
  </Tab>

  <Tab title="Synced">
    Writes hit the local store first (optimistic) and replay against the server in the background. SSE keeps the local store fresh from the server.

    ```swift theme={null}
    let client = try await MarfaClient.synced(
      url: URL(string: "https://marfa.example.com")!,
      apiKey: "marfa_k1_...",
      storePath: "/path/to/store.sqlite"
    )

    await client.syncEngine?.start()

    // Writes are instant and durable even offline
    let note = try await client.items.create(
      CreateItemInput(type: "core.note", properties: ["body": .string("Hello")])
    )
    ```

    Best for: user-facing apps that need instant UI, offline tolerance, and multi-device consistency.
  </Tab>
</Tabs>

Two more factories cover common auth patterns:

* `MarfaClient.fromEnvironment()` — reads `MARFA_API_URL` and `MARFA_API_KEY`. Returns `nil` if unset.
* `MarfaClient.fromKeychain(service:account:url:accessGroup:)` — loads the API key from the system Keychain. Pair with `client.saveToKeychain(service:account:accessGroup:)` to persist one.

## Configuration

`ClientConfiguration` controls retry, timeout, conflict strategy, and CDN routing:

```swift theme={null}
var config = ClientConfiguration(url: url, apiKey: key)
config.conflictStrategy = .auto         // or .manual, .callback
config.timeoutInterval = 30
config.resourceTimeout = 120
config.cdnBaseURL = URL(string: "https://cdn.marfa.example.com")  // optional
config.debugLogging = true              // full-body logging at .private

let client = MarfaClient(configuration: config)
```

`retryPolicy` on the configuration controls retry behavior for transient errors — bounded exponential backoff with jitter.

## Where next

The rest of the Swift SDK surface splits across five focused pages: [Authentication](/sdks/swift/authentication) for OAuth 2.1 and Keychain helpers, [Data access](/sdks/swift/data-access) for items / edges / metadata / extensions / blobs / search, [Typed models](/sdks/swift/typed-models) for `CoreNote` and custom-type codegen, [Sync engine](/sdks/swift/sync-engine) for SwiftUI reactive queries and the SSE replay loop, and [Errors and testing](/sdks/swift/errors-and-testing) for conflict handling, error types, and `MarfaSDKTestSupport`.
