Skip to Content
LearnCore ConceptsOffline-First

Offline-First Architecture

Gluonic is designed to work perfectly with or without network connectivity. Your application remains fully functional offline, with changes syncing automatically when connection is restored.

The Problem

Traditional apps break without network:

  • Can’t load data
  • Can’t save changes
  • Show error messages
  • Frustrate users

Result: Poor user experience, especially on mobile.

The Gluonic Solution

Store data locally first, sync to server in background:

User Action → Local Database → Background Sync → Server Instant UI Update ✓

How It Works

1. Local-First Storage

All data lives in a local database on the device:

  • React Native: Local storage via Drizzle adapter (OP-SQLite)
  • Web: Local storage via Drizzle adapter (better-sqlite3)
  • Electron: Local storage via Drizzle adapter (better-sqlite3)
// All reads come from local database - instant! const posts = useCollectionModels<Post>('post') // No network request ✓

2. Background Synchronization

Changes sync to server when network available:

// User edits a post await store.save('post', '123', { title: 'New Title' }) // What happens: // 1. ✓ Update local database (instant) // 2. ✓ Update UI (instant) // 3. ⏳ Queue for server sync (background) // 4. 🌐 Send to server when online // 5. ✓ Confirm or rollback

3. Smart Queue Management

Pending changes survive app restarts:

// User makes edits offline await store.save('post', '123', { title: 'Offline Edit' }) // Queued in local database ✓ // User closes app // ... // User reopens app (still offline) // Queue is restored automatically ✓ // Pending edits visible immediately ✓ // Network comes back // Queue processes automatically ✓

Benefits

🚀 Instant App Startup

No loading spinners waiting for network:

// Traditional app const [posts, setPosts] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { fetch('/api/posts') .then(res => res.json()) .then(data => { setPosts(data) setLoading(false) // Finally! 😤 }) .catch(() => setError(true)) // Network error 💥 }, []) // Gluonic const posts = useCollectionModels<Post>('post') // Data available immediately from local DB ✓ // No loading state needed ✓ // Works offline ✓

📱 Works Anywhere

Your app functions in:

  • ✈️ Airplane mode
  • 🚇 Subway tunnels
  • 🏔️ Rural areas
  • 🏢 Basement offices
  • 📶 Poor cell coverage

🎯 Better UX

Users never see:

  • ❌ “No internet connection” errors
  • ❌ Blank screens
  • ❌ Loading spinners
  • ❌ Disabled buttons

Instead they see:

  • ✅ Instant data
  • ✅ Working features
  • ✅ Smooth experience
  • ✅ Subtle sync indicator

Example: Field App

Imagine a service technician using your app:

Traditional App:

Site Visit → Open App → Wait for network... → Timeout! → Can't log service ❌

Gluonic App:

Site Visit → Open App → Instant data ✓ → Log service ✓ → Auto-sync later ✓

Network State Handling

Gluonic tracks connection state automatically:

import { observer, useConnectionState } from '@gluonic/client' const SyncIndicator = observer(() => { const { isOnline, isSyncing, queueLength } = useConnectionState() if (!isOnline && queueLength > 0) { return <Badge>Offline - {queueLength} pending</Badge> } if (isSyncing) { return <Badge>Syncing...</Badge> } return <Badge>Synced ✓</Badge> })

Architecture

┌─────────────────────────────────────────┐ │ React Components │ │ (Always read from local database) │ └────────────────┬────────────────────────┘ ┌────────────────▼────────────────────────┐ │ Local Database │ │ - SQLite (React Native) │ │ - IndexedDB (Web) │ │ - Always available ✓ │ └────────────────┬────────────────────────┘ │ Background Sync │ (when online) ┌─────────────────────────────────────────┐ │ Remote Server │ │ - PostgreSQL, MongoDB, etc. │ │ - Authoritative source of truth │ └─────────────────────────────────────────┘

Best Practices

DO ✅

  • Trust local data - It’s the source of truth for UI
  • Show sync status subtly - Small indicator, not blocking
  • Queue operations - Let sync happen in background
  • Handle conflicts gracefully - Server wins, notify user

DON’T ❌

  • Block on network - Never wait for server to show UI
  • Show errors prominently - Offline isn’t an error state
  • Disable features - Everything should work offline
  • Clear local data easily - Users expect persistence

Comparison to Other Approaches

ApproachNetwork RequiredStartup TimeOffline Support
Traditional REST✅ YesSlow (network RTT)❌ None
Apollo Client⚠️ First loadMedium⚠️ Manual setup
React Query⚠️ First loadMedium⚠️ Cache-based
Gluonic❌ NoInstant✅ Built-in

Next Steps

Last updated on