Calendar SDK

A published 6-package TypeScript SDK unifying Google Calendar, Microsoft Graph, and CalDAV behind one provider-agnostic API - bring your own OAuth, bring your own storage.

I’d already built one calendar integration - Friday talks to Google Calendar - and the thought of vendoring a second, completely different SDK just to add Outlook support was unappealing. Google Calendar, Microsoft Graph, and CalDAV each model events, sync, and auth differently, and none of them agree on shape. So I built the abstraction I actually wanted: one API, three providers underneath it.

One API, swappable providers

sdk.calendars.list(), sdk.events.create(), sdk.availability.freeBusy() - these calls work identically no matter which provider is registered. Swapping createGoogleProvider for createMicrosoftProvider is the only code that changes; the rest of the calling code doesn’t know or care which calendar backend it’s actually talking to.

Six packages, not one

The core package (@calendar-sdk/core) holds the unified services, a StorageAdapter interface, hooks, and a retrying transport layer - but it doesn’t ship any provider by default. Each provider (@calendar-sdk/google, @calendar-sdk/microsoft, @calendar-sdk/caldav) is its own package, so a consumer who only needs Google Calendar doesn’t pull in Microsoft Graph’s dependencies. OAuth flow, token refresh, and encrypted token-set storage live in a standalone @calendar-sdk/auth package, reusable on its own outside the calendar context entirely. A @calendar-sdk/mock provider gives an in-memory implementation for tests and examples with zero network calls or credentials required.

Bring your own everything

The SDK deliberately doesn’t own persistence or OAuth credentials - callers implement StorageAdapter against their own database and supply their own client ID/secret. That’s the actual value proposition next to a paid unified-calendar API: no vendor lock-in on where tokens live, at the cost of a bit more setup than a hosted service would require.

Key decisions

Built with