DEV Community

Cover image for ctrodb 1.4: Offline Sync for the Browser, Zero Dependencies
Odejobi Abiola Samuel
Odejobi Abiola Samuel

Posted on

ctrodb 1.4: Offline Sync for the Browser, Zero Dependencies

ctrodb is a client-side database for TypeScript. Schema validation, MongoDB-like queries, full-text search, relations — all in about 8KB gzipped with zero runtime dependencies.

v1.4 is the biggest release yet. It adds offline sync.

npm install ctrodb
Enter fullscreen mode Exit fullscreen mode

GitHub: github.com/ctrotech-tutor/ctrodb
Docs: ctrodb.vercel.app/docs

What's in v1.4

Sync engine with change tracking. Every create, update, and delete is recorded in a local change log and pushed to your server when connectivity returns.

import { Database, syncPlugin, HttpTransport } from "ctrodb"

const transport = new HttpTransport({
  url: "https://api.myapp.com/sync",
})

const db = new Database({
  name: "my-app",
  schema: { ... },
  plugins: [syncPlugin({ transport })],
})

await db.connect()
Enter fullscreen mode Exit fullscreen mode

Three conflict strategies out of the box — last-write-wins, client-wins, server-wins — plus a custom resolver hook. Field-level merge isn't built in as a strategy but you can implement it in the custom resolver.

const db = new Database({
  name: "my-app",
  schema: { ... },
  plugins: [syncPlugin({
    transport,
    strategy: "custom",
    conflictResolver: (conflict) => {
      return { resolution: "merged", merged: { ...conflict.local, ...conflict.remote } }
    },
  })],
})
Enter fullscreen mode Exit fullscreen mode

HTTP transport works with any backend. WebSocket transport for real-time push. Trigger sync manually, on interval, or let the auto-sync handle it.

await db.sync()
Enter fullscreen mode Exit fullscreen mode

React hooks for sync status and queue inspection:

import { useSyncStatus, useSyncQueue } from "ctrodb/react"

function SyncIndicator() {
  const { isSyncing, pendingChanges } = useSyncStatus()
  if (isSyncing) return <span>Syncing...</span>
  if (pendingChanges > 0) return <span>{pendingChanges} pending</span>
  return <span>All changes saved</span>
}
Enter fullscreen mode Exit fullscreen mode

Devtools component for debugging:

import { SyncDevPanel } from "ctrodb/react"

// Shows queue, event log, manual sync trigger
if (import.meta.env.DEV) <SyncDevPanel />
Enter fullscreen mode Exit fullscreen mode

Devtools utilities — inspect, retry, compact, stats — all take the database instance:

import { inspectSyncQueue, retryFailedSync, getSyncStats, compactSyncQueue } from "ctrodb"

const queue = await inspectSyncQueue(db)
const stats = await getSyncStats(db)
await retryFailedSync(db)
Enter fullscreen mode Exit fullscreen mode

What else

  • New useDoc hook for single-record subscriptions
  • useSync hook for manual sync control with event callbacks
  • DatabaseProvider for React context
  • Custom adapter support
  • CDN usage (IIFE build in npm package)

Links

Zero dependencies. Runs in the browser and Node.js. MIT license.

Top comments (0)