supabase-offline-sync — supabase-offline-sync install supabase-offline-sync, Steps-to-recovery, community, supabase-offline-sync install, ide skills, queue-based sync architecture, offline-first Expo apps, SQLite and Supabase integration, Claude Code, Cursor, Windsurf

v1.0.0
GitHub

About this Skill

Perfect for Mobile App Agents needing seamless offline data synchronization with Supabase and SQLite supabase-offline-sync is a queue-based sync architecture for offline-first Expo apps using SQLite and Supabase, enabling seamless data synchronization between local and remote databases.

Features

Implements a queue-based sync architecture using SQLite and Supabase
Utilizes a background worker for syncing data between local and remote databases
Supports retry on failure for ensuring data consistency
Creates a sync queue table with id, table_name, record_id, and operation columns
Enforces data integrity with CHECK constraints on operation types

# Core Topics

RipKDR RipKDR
[0]
[0]
Updated: 3/8/2026

Agent Capability Analysis

The supabase-offline-sync skill by RipKDR is an open-source community AI agent skill for Claude Code and other IDE workflows, helping agents execute tasks with better context, repeatability, and domain-specific guidance. Optimized for supabase-offline-sync install, queue-based sync architecture, offline-first Expo apps.

Ideal Agent Persona

Perfect for Mobile App Agents needing seamless offline data synchronization with Supabase and SQLite

Core Value

Empowers agents to build offline-first Expo apps with a queue-based sync architecture, utilizing SQLite for local storage and Supabase for cloud synchronization, ensuring reliable data consistency across online and offline modes

Capabilities Granted for supabase-offline-sync

Implementing offline data caching for mobile apps
Synchronizing local SQLite databases with Supabase in the background
Handling retry mechanisms for failed sync operations

! Prerequisites & Limits

  • Requires Supabase and SQLite integration
  • Expo app environment necessary
  • Queue-based sync architecture may introduce additional complexity
Labs Demo

Browser Sandbox Environment

⚡️ Ready to unleash?

Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.

Boot Container Sandbox

supabase-offline-sync

Install supabase-offline-sync, an AI agent skill for AI agent workflows and automation. Works with Claude Code, Cursor, and Windsurf with one-command setup.

SKILL.md
Readonly

Supabase Offline-First Sync

Queue-based sync architecture for offline-first Expo apps using SQLite and Supabase.

Architecture Overview

Local Write → SQLite → Sync Queue → Background Worker → Supabase
                              ↑____________↓ (retry on failure)

Database Schema

Sync Queue Table

sql
1CREATE TABLE sync_queue ( 2 id INTEGER PRIMARY KEY AUTOINCREMENT, 3 table_name TEXT NOT NULL, 4 record_id TEXT NOT NULL, 5 operation TEXT NOT NULL CHECK (operation IN ('INSERT', 'UPDATE', 'DELETE')), 6 data TEXT, -- JSON string for INSERT/UPDATE 7 retry_count INTEGER DEFAULT 0, 8 error_message TEXT, 9 created_at INTEGER NOT NULL, 10 processed_at INTEGER 11); 12 13CREATE INDEX idx_sync_queue_created ON sync_queue(created_at); 14CREATE INDEX idx_sync_queue_processed ON sync_queue(processed_at) WHERE processed_at IS NULL;

Core Implementation

1. Queue Operations

typescript
1interface SyncQueueItem { 2 id?: number; 3 table_name: string; 4 record_id: string; 5 operation: 'INSERT' | 'UPDATE' | 'DELETE'; 6 data?: string; 7 retry_count: number; 8 created_at: number; 9} 10 11async function enqueueSync( 12 db: SQLiteDatabase, 13 table: string, 14 recordId: string, 15 operation: 'INSERT' | 'UPDATE' | 'DELETE', 16 data?: object, 17): Promise<void> { 18 await db.runAsync( 19 `INSERT INTO sync_queue (table_name, record_id, operation, data, retry_count, created_at) 20 VALUES (?, ?, ?, ?, 0, ?)`, 21 table, 22 recordId, 23 operation, 24 data ? JSON.stringify(data) : null, 25 Date.now(), 26 ); 27}

2. Process Queue

typescript
1async function processSyncQueue(db: SQLiteDatabase, supabase: SupabaseClient): Promise<void> { 2 const pending = await db.getAllAsync<SyncQueueItem>( 3 `SELECT * FROM sync_queue 4 WHERE processed_at IS NULL AND retry_count < 5 5 ORDER BY created_at ASC 6 LIMIT 50`, 7 ); 8 9 // Process DELETEs first to avoid FK conflicts 10 const deletes = pending.filter((p) => p.operation === 'DELETE'); 11 const others = pending.filter((p) => p.operation !== 'DELETE'); 12 13 for (const item of [...deletes, ...others]) { 14 try { 15 await processQueueItem(db, supabase, item); 16 } catch (error) { 17 await markFailed(db, item.id!, error.message); 18 } 19 } 20}

3. Process Individual Item

typescript
1async function processQueueItem( 2 db: SQLiteDatabase, 3 supabase: SupabaseClient, 4 item: SyncQueueItem, 5): Promise<void> { 6 const { error } = await supabase.from(item.table_name).upsert( 7 { 8 id: item.record_id, 9 ...(item.data ? JSON.parse(item.data) : {}), 10 updated_at: new Date().toISOString(), 11 }, 12 { onConflict: 'id' }, 13 ); 14 15 if (error) throw error; 16 17 // Mark as processed 18 await db.runAsync('UPDATE sync_queue SET processed_at = ? WHERE id = ?', Date.now(), item.id); 19}

React Integration

Sync Context Provider

typescript
1export function SyncProvider({ children }: { children: React.ReactNode }) { 2 const { db } = useDatabase(); 3 const { supabase } = useSupabase(); 4 const netInfo = useNetInfo(); 5 6 useEffect(() => { 7 if (!db || !supabase || !netInfo.isConnected) return; 8 9 // Sync on connection restore 10 const interval = setInterval(() => { 11 processSyncQueue(db, supabase); 12 }, 30000); // Every 30 seconds 13 14 return () => clearInterval(interval); 15 }, [db, supabase, netInfo.isConnected]); 16 17 return children; 18}

Optimistic Updates Pattern

typescript
1function useCreateJournal() { 2 const queryClient = useQueryClient(); 3 const { db } = useDatabase(); 4 5 return useMutation({ 6 mutationFn: async (entry: JournalEntry) => { 7 // 1. Save locally 8 await db.runAsync( 9 'INSERT INTO journal (id, encrypted_body, created_at) VALUES (?, ?, ?)', 10 entry.id, 11 await encryptContent(entry.content), 12 entry.created_at, 13 ); 14 15 // 2. Queue for sync 16 await enqueueSync(db, 'journal', entry.id, 'INSERT', entry); 17 18 return entry; 19 }, 20 onSuccess: () => { 21 queryClient.invalidateQueries({ queryKey: ['journal'] }); 22 }, 23 }); 24}

Conflict Resolution

Last-write-wins with server timestamp:

typescript
1async function resolveConflict(local: JournalEntry, remote: JournalEntry): Promise<JournalEntry> { 2 const localTime = new Date(local.updated_at).getTime(); 3 const remoteTime = new Date(remote.updated_at).getTime(); 4 5 return remoteTime > localTime ? remote : local; 6}

Background Sync (Expo)

typescript
1import * as BackgroundFetch from 'expo-background-fetch'; 2import * as TaskManager from 'expo-task-manager'; 3 4const SYNC_TASK = 'background-sync'; 5 6TaskManager.defineTask(SYNC_TASK, async () => { 7 const db = await openDatabase(); 8 const supabase = createClient(); 9 10 try { 11 await processSyncQueue(db, supabase); 12 return BackgroundFetch.BackgroundFetchResult.NewData; 13 } catch { 14 return BackgroundFetch.BackgroundFetchResult.Failed; 15 } 16}); 17 18async function registerBackgroundSync() { 19 await BackgroundFetch.registerTaskAsync(SYNC_TASK, { 20 minimumInterval: 15 * 60, // 15 minutes 21 stopOnTerminate: false, 22 startOnBoot: true, 23 }); 24}

Retry Strategy

Exponential backoff for failed items:

typescript
1async function markFailed(db: SQLiteDatabase, queueId: number, error: string): Promise<void> { 2 await db.runAsync( 3 `UPDATE sync_queue 4 SET retry_count = retry_count + 1, 5 error_message = ?, 6 created_at = ? -- Delay retry 7 WHERE id = ?`, 8 error, 9 Date.now() + Math.pow(2, retry_count) * 60000, // Exponential backoff 10 queueId, 11 ); 12}

Best Practices

  1. Process DELETEs first - Avoids foreign key constraint errors
  2. Batch operations - Process 50 items at a time
  3. Encrypt before sync - Never send plaintext sensitive data
  4. User-scoped sync - Always filter by user_id in Supabase RLS
  5. Retry limit - Max 5 retries before manual intervention
  6. Conflict timestamps - Use updated_at for last-write-wins

FAQ & Installation Steps

These questions and steps mirror the structured data on this page for better search understanding.

? Frequently Asked Questions

What is supabase-offline-sync?

Perfect for Mobile App Agents needing seamless offline data synchronization with Supabase and SQLite supabase-offline-sync is a queue-based sync architecture for offline-first Expo apps using SQLite and Supabase, enabling seamless data synchronization between local and remote databases.

How do I install supabase-offline-sync?

Run the command: npx killer-skills add RipKDR/Steps-to-recovery/supabase-offline-sync. It works with Cursor, Windsurf, VS Code, Claude Code, and 19+ other IDEs.

What are the use cases for supabase-offline-sync?

Key use cases include: Implementing offline data caching for mobile apps, Synchronizing local SQLite databases with Supabase in the background, Handling retry mechanisms for failed sync operations.

Which IDEs are compatible with supabase-offline-sync?

This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.

Are there any limitations for supabase-offline-sync?

Requires Supabase and SQLite integration. Expo app environment necessary. Queue-based sync architecture may introduce additional complexity.

How To Install

  1. 1. Open your terminal

    Open the terminal or command line in your project directory.

  2. 2. Run the install command

    Run: npx killer-skills add RipKDR/Steps-to-recovery/supabase-offline-sync. The CLI will automatically detect your IDE or AI agent and configure the skill.

  3. 3. Start using the skill

    The skill is now active. Your AI agent can use supabase-offline-sync immediately in the current project.

Related Skills

Looking for an alternative to supabase-offline-sync or another community skill for your workflow? Explore these related open-source skills.

View All

widget-generator

Logo of f
f

f.k.a. Awesome ChatGPT Prompts. Share, discover, and collect prompts from the community. Free and open source — self-host for your organization with complete privacy.

149.6k
0
AI

flags

Logo of vercel
vercel

flags is a Next.js feature management skill that enables developers to efficiently add or modify framework feature flags, streamlining React application development.

138.4k
0
Browser

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
AI

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
AI