Header BackgroundHeader BackgroundHeader BackgroundHeader BackgroundSebastian

Designing the Public API

With the event sourcing foundation in place, the next step was designing the public API that app developers actually use. The goal: a clean, minimal interface that hides all internal complexity.

Design Principles

Several principles guided the API design:

  • Storage is transparent — the SDK manages local storage internally
  • Backends are the only config — user provides client ID/secret + folder
  • Auth tokens are internal — managed by Syncraft, not the app developer
  • All reads are local — no network calls on get(), ever
  • Writes auto-push — debounced push after every write
  • Events for allonChange, onSync, onError callbacks

TypeScript and Go

Both SDKs follow the same pattern—CRUD operations, sync, and event subscription:

const client = await Syncraft.init({
  namespace: 'home-inventory',
  backends: [
    { type: 'gdrive', clientId: '...', clientSecret: '...', folderId: '...' },
  ],
});

await client.put('items', 'abc', { name: 'Hammer', quantity: 5 });
const item = await client.get('items', 'abc');
await client.sync();

The Go version uses function options for configuration, idiomatic for the ecosystem.

Sync Behavior

Periodic sync is pull-only (every 5 minutes by default). Push happens after local writes, debounced at 500ms. Manual sync() triggers both pull and push. Conflict resolution uses LWW with nested field diffs for minimal changes.


The public API demonstrates the power of good abstraction. By hiding the event sourcing, multi-backend sync, and change log management behind a simple CRUD interface, Syncraft becomes accessible to any developer. The parallel structure between TypeScript and Go ensures consistency across ecosystems.

AI Insights: API as Abstraction