# Install (https://www.cal-sdk.com/docs/installation)

calsdk is split into a core package and one package per calendar, so your app only installs the providers it talks to. Start with `@cal-sdk/core` and one provider:

```npm
npm install @cal-sdk/core @cal-sdk/google
```

## Pick your providers [#pick-your-providers]

| Calendar                                 | Package             | Function                        |
| ---------------------------------------- | ------------------- | ------------------------------- |
| Google Calendar                          | `@cal-sdk/google`    | `google()`                      |
| Microsoft Outlook                        | `@cal-sdk/microsoft` | `microsoft()`                   |
| iCloud, Zoho Calendar, any CalDAV server | `@cal-sdk/caldav`    | `icloud()`, `zoho()`, `caldav()` |
| Cal.com                                  | `@cal-sdk/calcom`    | `calcom()`                      |
| Calendly                                 | `@cal-sdk/calendly`  | `calendly()`                    |
| Zoom                                     | `@cal-sdk/zoom`      | `zoom()`                        |
| ICS feeds                                | `@cal-sdk/ics`       | `ics()`                         |
| In-memory, for tests and examples        | `@cal-sdk/mock`      | `mockCalendar()`                |

Not sure which one fits? [Choose a provider](/docs/choose-a-provider) walks through the credentials each one needs.

## Requirements [#requirements]

Every package is ESM only. Providers talk to their APIs with `fetch` and nothing else, so they run on Node.js 20 or later, Bun, Deno and edge runtimes. CI checks this by running the quickstart in Deno with no file, network or environment access.

TypeScript is optional, but worth it here. Provider options and metadata are typed by the provider you pass, so typos are caught before they reach an API.

## Keep credentials on the server [#keep-credentials-on-the-server]

Providers take OAuth access tokens, API keys or app passwords, which is everything someone needs to read and change a user's calendar. Create providers in server code, such as a route handler, a server action or a background job, and never ship them to the browser.

calsdk doesn't run OAuth flows or refresh tokens: your app owns the user's account, so it owns the tokens too. Pass a token, or a function that returns a fresh one. calsdk calls the function before each request, so it can refresh and cache tokens however your app already does:

```ts
import { google } from '@cal-sdk/google';

const calendar = google({
  accessToken: async () => {
    const account = await db.calendarAccounts.find(userId);
    return account.expiresAt > Date.now() ? account.accessToken : refresh(account);
  },
});
```

<Cards>
  <Card title="Next: run the quickstart" href="/docs/quickstart">
    Create, list and move events on an in-memory calendar before adding credentials.
  </Card>
</Cards>
