Skip to main content
Chat sync is optional and off by default — chat history stays local-only in SwiftData until you enable it. The complete setup guide lives at docs/integrations/ChatSync.md in your project.

What Is Chat Sync?

Offline-First

Writes go to the local database first

Background Sync

Syncs to cloud in background

Cross-Device

Access from all devices

Optional

Enable only when needed

Quick Overview

1

Run Migration

Create Supabase tables:
# In Supabase Dashboard SQL Editor
# Run: supabase/migrations/20241016000000_chat_sync.sql
2

Enable the Feature Flag

Flip the chatSyncEnabled flag in SwiftAIBoilerplatePro/Composition/FeatureFlags.swift. By default it is false in DEBUG and reads the CHAT_SYNC_ENABLED environment variable in Release:
public static var chatSyncEnabled: Bool {
    #if DEBUG
    return false // Off by default in debug — change to true to test locally
    #else
    return ProcessInfo.processInfo.environment["CHAT_SYNC_ENABLED"] == "true"
    #endif
}
3

Uncomment the Supabase Implementations

Both Supabase repositories ship commented out until the Supabase dependency is added. Uncomment them in the Storage package:
  • Packages/Storage/Sources/Storage/Repositories/SupabaseConversationRepository.swift
  • Packages/Storage/Sources/Storage/Repositories/SupabaseMessageRepository.swift
4

Wire Up the Hybrid Repositories in CompositionRoot

In SwiftAIBoilerplatePro/Composition/CompositionRoot.swift, the chat-sync branch currently falls back to the local repositories (a // TODO: wire Supabase remote repos once a signed-in user id is available marks the spot). Replace that with the hybrid repositories once you have a signed-in user id:
self.conversationRepository = HybridConversationRepository(
    local: localConversationRepo,
    remote: remoteConversationRepo
)
self.messageRepository = HybridMessageRepository(
    local: localMessageRepo,
    remote: remoteMessageRepo
)

How It Works

Write Flow:
User sends message → Local SwiftData (instant) → Background sync to Supabase

Read Flow:
App opens → Show local data (instant) → Background pull from Supabase → Update UI
HybridConversationRepository and HybridMessageRepository write to the local SwiftData store first and sync to the remote Supabase repository in a background Task. If the remote write fails, the local save still succeeds, so the app keeps working offline.

Prerequisites

  • Supabase project configured (see Supabase Setup)
  • Supabase dependency added to the Storage package
  • User authenticated

What You Get

  • Conversations and messages sync across devices
  • Offline-first behavior preserved (local writes never block on the network)
  • Background sync that degrades gracefully when the remote is unavailable

Complete Guide

The full docs/integrations/ChatSync.md guide covers the database schema, Row Level Security policies, repository implementations, the hybrid sync strategy, conflict resolution, testing, and troubleshooting.

View Complete Setup Guide

Full chat sync guide with architecture diagrams, in your project repo

Storage Module

Repository architecture

Profile Photos

Another optional sync feature

Supabase Setup

Required backend

Building Your App

Customize features

Need Help?

  • Troubleshooting section in the full docs/integrations/ChatSync.md guide
  • Create an issue
  • Check the Supabase Dashboard logs