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 all —
onChange,onSync,onErrorcallbacks
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.





