---
description: Capacitor Calendar plugin to create, read, update, and delete calendars and events on Android and iOS, including recurring events and alerts.
title: Capacitor Calendar Plugin for Android & iOS - Capawesome
image: https://capawesome.io/docs/assets/images/social/sdks/capacitor/calendar.png
---

<!doctype html> 

[Skip to content ](#capacitor-calendar-plugin) 

[📲 Introducing **Build Sharing** — get your builds onto testers' devices with a link & QR code. No account required. ](/blog/share-mobile-app-builds-with-testers/) 

* [ SDKs ](/docs/sdks/)
* [ iOS ](#ios)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Type Aliases ](#type-aliases)
* [ Enums ](#enums)
* [ Recurring Events ](#recurring-events)
* [ FAQ ](#faq)
* [ Related Plugins ](#related-plugins)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ Breaking Changes ](#breaking-changes)
* [ License ](#license)
* [ Clipboard ](/docs/sdks/capacitor/clipboard/)
* [ Cloudinary ](/docs/sdks/capacitor/cloudinary/)
* [ Compass ](/docs/sdks/capacitor/compass/)
* [ Contacts ](/docs/sdks/capacitor/contacts/)
* [ Crisp ](/docs/sdks/capacitor/crisp/)
* [ Datetime Picker ](/docs/sdks/capacitor/datetime-picker/)
* [ Device Info ](/docs/sdks/capacitor/device-info/)
* [ Dialog ](/docs/sdks/capacitor/dialog/)
* [ Document Scanner ](/docs/sdks/capacitor/document-scanner/)
* [ Electron ](/docs/sdks/capacitor/electron/)
* [ Exif ](/docs/sdks/capacitor/exif/)
* [ Facebook Sign-In ](/docs/sdks/capacitor/facebook-sign-in/)
* [ File Compressor ](/docs/sdks/capacitor/file-compressor/)
* [ File Manager ](/docs/sdks/capacitor/file-manager/)
* [ File Opener ](/docs/sdks/capacitor/file-opener/)
* [ File Picker ](/docs/sdks/capacitor/file-picker/)
* [ File Transfer ](/docs/sdks/capacitor/file-transfer/)
* [ Firebase ](/docs/sdks/capacitor/firebase/)
* [ Formbricks ](/docs/sdks/capacitor/formbricks/)
* [ Geocoder ](/docs/sdks/capacitor/geocoder/)
* [ Geofences ](/docs/sdks/capacitor/geofences/)
* [ Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [ Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [ Gyroscope ](/docs/sdks/capacitor/gyroscope/)
* [ Haptics ](/docs/sdks/capacitor/haptics/)
* [ Health ](/docs/sdks/capacitor/health/)
* [ Home Indicator ](/docs/sdks/capacitor/home-indicator/)
* [ In-App Browser ](/docs/sdks/capacitor/in-app-browser/)
* [ Install Referrer ](/docs/sdks/capacitor/install-referrer/)
* [ Intercom ](/docs/sdks/capacitor/intercom/)
* [ Intune ](/docs/sdks/capacitor/intune/)
* [ Keep Awake ](/docs/sdks/capacitor/keep-awake/)
* [ libSQL ](/docs/sdks/capacitor/libsql/)
* [ Light Sensor ](/docs/sdks/capacitor/light-sensor/)
* [ Live Update ](/docs/sdks/capacitor/live-update/)
* [ LLM ](/docs/sdks/capacitor/llm/)
* [ Localization ](/docs/sdks/capacitor/localization/)
* [ Mail Composer ](/docs/sdks/capacitor/mail-composer/)
* [ Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [ MapLibre ](/docs/sdks/capacitor/maplibre/)
* [ Maps Launcher ](/docs/sdks/capacitor/maps-launcher/)
* [ Media Session ](/docs/sdks/capacitor/media-session/)
* [ ML Kit ](/docs/sdks/capacitor/mlkit/)
* [ Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [ Network ](/docs/sdks/capacitor/network/)
* [ NFC ](/docs/sdks/capacitor/nfc/)
* [ Node.js ](/docs/sdks/capacitor/nodejs/)
* [ OAuth ](/docs/sdks/capacitor/oauth/)
* [ Passkeys ](/docs/sdks/capacitor/passkeys/)
* [ Password Autofill ](/docs/sdks/capacitor/password-autofill/)
* [ PDF Generator ](/docs/sdks/capacitor/pdf-generator/)
* [ PDF Viewer ](/docs/sdks/capacitor/pdf-viewer/)
* [ Pedometer ](/docs/sdks/capacitor/pedometer/)
* [ Permissions ](/docs/sdks/capacitor/permissions/)
* [ Phone Dialer ](/docs/sdks/capacitor/phone-dialer/)
* [ Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [ Photo Manipulator ](/docs/sdks/capacitor/photo-manipulator/)
* [ PixLive ](/docs/sdks/capacitor/pixlive/)
* [ PostHog ](/docs/sdks/capacitor/posthog/)
* [ Printer ](/docs/sdks/capacitor/printer/)
* [ Privacy Screen ](/docs/sdks/capacitor/privacy-screen/)
* [ Proximity Sensor ](/docs/sdks/capacitor/proximity-sensor/)
* [ Purchases ](/docs/sdks/capacitor/purchases/)
* [ RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [ Root Detection ](/docs/sdks/capacitor/root-detection/)
* [ Screen Brightness ](/docs/sdks/capacitor/screen-brightness/)
* [ Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [ Screen Reader ](/docs/sdks/capacitor/screen-reader/)
* [ Screenshot ](/docs/sdks/capacitor/screenshot/)
* [ Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [ Settings Launcher ](/docs/sdks/capacitor/settings-launcher/)
* [ Shake ](/docs/sdks/capacitor/shake/)
* [ Silent Mode ](/docs/sdks/capacitor/silent-mode/)
* [ SIM ](/docs/sdks/capacitor/sim/)
* [ SMS Composer ](/docs/sdks/capacitor/sms-composer/)
* [ Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [ Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [ Share Target ](/docs/sdks/capacitor/share-target/)
* [ Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [ SQLite ](/docs/sdks/capacitor/sqlite/)
* [ Superwall ](/docs/sdks/capacitor/superwall/)
* [ System WebView ](/docs/sdks/capacitor/system-webview/)
* [ Tauri ](/docs/sdks/capacitor/tauri/)
* [ Text Interaction ](/docs/sdks/capacitor/text-interaction/)
* [ Text Zoom ](/docs/sdks/capacitor/text-zoom/)
* [ Thermal State ](/docs/sdks/capacitor/thermal-state/)
* [ Toast ](/docs/sdks/capacitor/toast/)
* [ Torch ](/docs/sdks/capacitor/torch/)
* [ Vault ](/docs/sdks/capacitor/vault/)
* [ Volume ](/docs/sdks/capacitor/volume/)
* [ Wallet ](/docs/sdks/capacitor/wallet/)
* [ Watch ](/docs/sdks/capacitor/watch/)
* [ Wifi ](/docs/sdks/capacitor/wifi/)
* [ YouTube Player ](/docs/sdks/capacitor/youtube-player/)
* [ Zip ](/docs/sdks/capacitor/zip/)
* [ Cordova ](/docs/sdks/cordova/)
* [ Cloud ](/docs/cloud/)
* [ Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [ Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [ FAQ ](/docs/cloud/live-updates/faq/)
* [ Native Builds ](/docs/cloud/native-builds/)
* [ Set Up Environments ](/docs/cloud/native-builds/environments/)
* [ Set Up Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [ Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [ Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [ Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [ Use pnpm, Yarn, or bun ](/docs/cloud/native-builds/package-managers/)
* [ Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [ Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [ Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [ Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [ Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [ Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [ Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [ FAQ ](/docs/cloud/native-builds/faq/)
* [ App Store Publishing ](/docs/cloud/app-store-publishing/)
* [ Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [ Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [ Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [ FAQ ](/docs/cloud/app-store-publishing/faq/)
* [ Automations ](/docs/cloud/automations/)
* [ Reference ](/docs/cloud/automations/reference/)
* [ Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [ FAQ ](/docs/cloud/automations/faq/)
* [ Assist ](/docs/cloud/assist/)
* [ CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [ Webhooks ](/docs/cloud/webhooks/)
* [ Integrations ](/docs/cloud/integrations/)
* Notifications
* Account
* [ Organization ](/docs/cloud/organizations/)
* [ Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [ Network Restrictions ](/docs/cloud/organizations/network-restrictions/)
* [ Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [ Billing ](/docs/cloud/organizations/billing/)
* [ License Keys ](/docs/cloud/license-keys/)
* [ AI ](/docs/ai/)
* [ Insiders ](/docs/insiders/)
* [ Billing & Plans ](/docs/insiders/billing-and-plans/)
* [ FAQ ](/docs/insiders/faq/)
* [ License ](https://capawesome.io/legal/eula/)
* [ Support ](/docs/support/)
* [ Contributing ](/docs/contributing/)
* Contributing code
* [ Code of Conduct ](/docs/contributing/code-of-conduct/)
* [ Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [ Blog ](/blog/)
* Categories

* [ iOS ](#ios)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Type Aliases ](#type-aliases)
* [ Enums ](#enums)
* [ Recurring Events ](#recurring-events)
* [ FAQ ](#faq)
* [ Related Plugins ](#related-plugins)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ Breaking Changes ](#breaking-changes)
* [ License ](#license)

Build and Ship Mobile Apps Faster

Cloud builds, OTA live updates, and automated store releases — everything your mobile team needs in one platform.

[Start for free ](https://console.cloud.capawesome.io/?utm%5Fsource=docs&utm%5Fmedium=sidebar%5Fcta&utm%5Fcampaign=docs%5Fcta) [See our plans ](https://capawesome.io/pricing/?utm%5Fsource=docs&utm%5Fmedium=sidebar%5Fcta&utm%5Fcampaign=docs%5Fcta) 

# Capacitor Calendar Plugin[¶](#capacitor-calendar-plugin "Permanent link")

Capacitor plugin to manage calendars and events on Android and iOS. Create, read, update and delete calendars and events, work with recurring events, present the system event dialogs, and listen for calendar changes.

[ ![Deliver Live Updates to your Capacitor app with Capawesome Cloud](../../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](https://cloud.capawesome.io/) 

## Features[¶](#features "Permanent link")

The Capacitor Calendar plugin gives your app full access to the calendars and events on the device. Here are some of the key features:

* 📅 **Calendars**: Create, delete and retrieve the calendars on the device, including the default calendar for new events.
* 🗓️ **Events**: Create, read, update and delete events, and query all events in a time range with a single call.
* 🔁 **Recurring Events**: Create recurring events with a readable recurrence rule — and read that rule back, instead of only being able to write it.
* 🎯 **Single Occurrences**: Update or delete a single occurrence of a recurring event, or the occurrence and all future ones.
* 📱 **System Dialogs**: Let the user create or edit an event in the system dialog, prefilled with your event data.
* 🔔 **Change Listener**: Get notified when calendars or events change, including changes made by other apps.
* 🔒 **Granular Permissions**: Separate read and write permissions, including write-only calendar access on iOS 17 and newer.
* ⚠️ **Error Codes**: Every runtime failure rejects with a documented error code, so you can branch on it instead of parsing messages.
* 🌍 **All-Day & Time Zones**: A documented all-day and time zone contract that behaves identically on both platforms — no off-by-one-day surprises.
* 🤝 **Compatibility**: Works hand in hand with the [Contacts](https://capawesome.io/docs/sdks/capacitor/contacts/) and [Datetime Picker](https://capawesome.io/docs/sdks/capacitor/datetime-picker/) plugins.
* 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
* 🔁 **Up-to-date**: Always supports the latest Capacitor version.
* ⭐️ **Support**: Priority support from the Capawesome Team.
* ✨ **Handcrafted**: Built from the ground up with care and expertise, not forked or AI-generated.

Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!

## Use Cases[¶](#use-cases "Permanent link")

The Calendar plugin is typically used whenever an app needs to read from or write to the calendars on the device, for example:

* **Booking and appointment apps**: Write a confirmed booking straight into the user's calendar, including an alert before the appointment, and update or remove it when the booking changes.
* **Field service and scheduling**: Show the agenda of the device next to your own schedule so that technicians and sales reps see conflicts before they accept a job.
* **Fitness and course apps**: Add recurring training sessions or course dates as a single recurring event, and let the user skip a single session without losing the series.
* **Reminders before appointments**: Attach alerts to an event so that the operating system reminds the user, even when your app is not running.
* **Calendar integrations**: Keep events in sync with your backend and react to changes that the user made in the calendar app.

## Compatibility[¶](#compatibility "Permanent link")

| Plugin Version | Capacitor Version | Status         |
| -------------- | ----------------- | -------------- |
| 0.x.x          | \>=8.x.x          | Active support |

## Demo[¶](#demo "Permanent link")

| Android | iOS |
| ------- | --- |

## Installation[¶](#installation "Permanent link")

This plugin is only available to [Capawesome Insiders](https://capawesome.io/insiders/). First, make sure you have the Capawesome npm registry set up. You can do this by running the following commands:

`[](#%5F%5Fcodelineno-0-1)npm config set @capawesome-team:registry https://npm.registry.capawesome.io
[](#%5F%5Fcodelineno-0-2)npm config set //npm.registry.capawesome.io/:_authToken <YOUR_LICENSE_KEY>
`

**Attention**: Replace `<YOUR_LICENSE_KEY>` with the license key you received from Polar. If you don't have a license key yet, you can get one by becoming a [Capawesome Insider](https://capawesome.io/insiders/).

Next, you can use our **AI-Assisted Setup** to install the plugin. Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:

`[](#%5F%5Fcodelineno-1-1)npx skills add capawesome-team/skills --skill capacitor-plugins
`

Then use the following prompt:

`` [](#%5F%5Fcodelineno-2-1)Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome-team/capacitor-calendar` plugin in my project.
 ``

If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:

`[](#%5F%5Fcodelineno-3-1)npm install @capawesome-team/capacitor-calendar
[](#%5F%5Fcodelineno-3-2)npx cap sync
`

### Android[¶](#android "Permanent link")

#### Permissions[¶](#permissions "Permanent link")

This API requires the following elements be added to your `AndroidManifest.xml` before or after the `application` tag:

`` [](#%5F%5Fcodelineno-4-1)<!-- Required if you want to read calendars and events, for example with `getCalendars()` or `getEvents(...)`. -->
[](#%5F%5Fcodelineno-4-2)<uses-permission android:name="android.permission.READ_CALENDAR" />
[](#%5F%5Fcodelineno-4-3)<!-- Required if you want to create, update or delete calendars and events, for example with `createEvent(...)`. -->
[](#%5F%5Fcodelineno-4-4)<uses-permission android:name="android.permission.WRITE_CALENDAR" />
 ``

Only declare the permissions that your app actually needs. Keep in mind that `createEvent(...)`, `updateEventById(...)` and `deleteEventById(...)` require the `READ_CALENDAR` permission in addition to the `WRITE_CALENDAR` permission, because they have to look up the calendar or event first. Only `createCalendar(...)` and `deleteCalendarById(...)` work with the `WRITE_CALENDAR` permission alone.

#### Proguard[¶](#proguard "Permanent link")

If you are using Proguard, you need to add the following rules to your `proguard-rules.pro` file:

`[](#%5F%5Fcodelineno-5-1)-keep class io.capawesome.capacitorjs.plugins.** { *; }
`

### iOS[¶](#ios "Permanent link")

#### Privacy Descriptions[¶](#privacy-descriptions "Permanent link")

Add the following keys to the `ios/App/App/Info.plist` file, which tell the user why your app needs access to the calendars:

`` [](#%5F%5Fcodelineno-6-1)<!-- Required on iOS 17 and newer if your app reads or modifies calendars or events. -->
[](#%5F%5Fcodelineno-6-2)<key>NSCalendarsFullAccessUsageDescription</key>
[](#%5F%5Fcodelineno-6-3)<string>The app needs access to your calendars to display and manage your events.</string>
[](#%5F%5Fcodelineno-6-4)<!-- Required on iOS 17 and newer if your app only requests the `writeCalendar` permission. -->
[](#%5F%5Fcodelineno-6-5)<key>NSCalendarsWriteOnlyAccessUsageDescription</key>
[](#%5F%5Fcodelineno-6-6)<string>The app needs access to your calendars to add events for your bookings.</string>
[](#%5F%5Fcodelineno-6-7)<!-- Required on iOS 16 and older. -->
[](#%5F%5Fcodelineno-6-8)<key>NSCalendarsUsageDescription</key>
[](#%5F%5Fcodelineno-6-9)<string>The app needs access to your calendars to display and manage your events.</string>
 ``

Which keys you need depends on the access that your app requests:

* `NSCalendarsFullAccessUsageDescription` is required on **iOS 17 and newer** whenever the `readCalendar` permission is requested and by every method that reads or modifies calendars or events. Modifying requires full access as well, because the plugin has to look up the calendar or event first.
* `NSCalendarsWriteOnlyAccessUsageDescription` is only required on **iOS 17 and newer** if `requestPermissions(...)` is called with only the `writeCalendar` permission. Write-only access lets your app add events without seeing the events of the user, but is not sufficient for the methods of this plugin.
* `NSCalendarsUsageDescription` is required on **iOS 16 and older**, which does not distinguish between read and write access.

If a required key is missing, `requestPermissions(...)` rejects with a clear error message.

## Configuration[¶](#configuration "Permanent link")

No configuration required for this plugin.

## Usage[¶](#usage "Permanent link")

The following examples show how to request permissions, work with calendars and events, create and modify recurring events, present the system event dialogs, and listen for calendar changes.

### Request permissions[¶](#request-permissions "Permanent link")

Request read and write access to the calendars of the device. Pass the `permissions` option to request only a subset. On iOS 17 and newer, requesting only the `writeCalendar` permission requests write-only access, which does not give your app access to the existing events of the user. Methods such as `createEvent(...)` request full access when they are called, because they have to look up the calendar or event first:

`[](#%5F%5Fcodelineno-7-1)import { Calendar } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-7-2)
[](#%5F%5Fcodelineno-7-3)const requestPermissions = async () => {
[](#%5F%5Fcodelineno-7-4)  const { readCalendar, writeCalendar } = await Calendar.requestPermissions();
[](#%5F%5Fcodelineno-7-5)  return readCalendar === 'granted' && writeCalendar === 'granted';
[](#%5F%5Fcodelineno-7-6)};
[](#%5F%5Fcodelineno-7-7)
[](#%5F%5Fcodelineno-7-8)const requestWriteOnlyPermission = async () => {
[](#%5F%5Fcodelineno-7-9)  const { writeCalendar } = await Calendar.requestPermissions({
[](#%5F%5Fcodelineno-7-10)    permissions: ['writeCalendar'],
[](#%5F%5Fcodelineno-7-11)  });
[](#%5F%5Fcodelineno-7-12)  return writeCalendar === 'granted';
[](#%5F%5Fcodelineno-7-13)};
`

### Get the calendars[¶](#get-the-calendars "Permanent link")

Retrieve all calendars on the device with `getCalendars()`, or only the calendar that the system uses for new events with `getDefaultCalendar()`. Use the `writable` property to filter out calendars that your app cannot write to, for example subscribed holiday calendars:

`[](#%5F%5Fcodelineno-8-1)import { Calendar } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-8-2)
[](#%5F%5Fcodelineno-8-3)const getWritableCalendars = async () => {
[](#%5F%5Fcodelineno-8-4)  const { calendars } = await Calendar.getCalendars();
[](#%5F%5Fcodelineno-8-5)  return calendars.filter(calendar => calendar.writable);
[](#%5F%5Fcodelineno-8-6)};
[](#%5F%5Fcodelineno-8-7)
[](#%5F%5Fcodelineno-8-8)const getDefaultCalendar = async () => {
[](#%5F%5Fcodelineno-8-9)  const { calendar } = await Calendar.getDefaultCalendar();
[](#%5F%5Fcodelineno-8-10)  return calendar;
[](#%5F%5Fcodelineno-8-11)};
`

### Create an event[¶](#create-an-event "Permanent link")

Create an event with `createEvent(...)`. Only `title` and `startDate` are required. If no `calendarId` is provided, the event is created in the default calendar. The `alerts` are offsets in minutes before the start of the event:

`[](#%5F%5Fcodelineno-9-1)import { Calendar, EventAvailability } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-9-2)
[](#%5F%5Fcodelineno-9-3)const createEvent = async (calendarId: string) => {
[](#%5F%5Fcodelineno-9-4)  const startDate = new Date('2026-09-01T10:00:00').getTime();
[](#%5F%5Fcodelineno-9-5)  const { id } = await Calendar.createEvent({
[](#%5F%5Fcodelineno-9-6)    event: {
[](#%5F%5Fcodelineno-9-7)      calendarId,
[](#%5F%5Fcodelineno-9-8)      title: 'Dentist appointment',
[](#%5F%5Fcodelineno-9-9)      startDate,
[](#%5F%5Fcodelineno-9-10)      endDate: startDate + 60 * 60 * 1000,
[](#%5F%5Fcodelineno-9-11)      location: 'Main Street 1, Springfield',
[](#%5F%5Fcodelineno-9-12)      description: 'Bring the insurance card.',
[](#%5F%5Fcodelineno-9-13)      availability: EventAvailability.Busy,
[](#%5F%5Fcodelineno-9-14)      alerts: [60, 15],
[](#%5F%5Fcodelineno-9-15)    },
[](#%5F%5Fcodelineno-9-16)  });
[](#%5F%5Fcodelineno-9-17)  return id;
[](#%5F%5Fcodelineno-9-18)};
`

### Create a recurring event[¶](#create-a-recurring-event "Permanent link")

Add a `recurrence` rule to create a recurring event. The following example creates an event that repeats every week on Mondays and Wednesdays for ten occurrences:

`[](#%5F%5Fcodelineno-10-1)import {
[](#%5F%5Fcodelineno-10-2)  Calendar,
[](#%5F%5Fcodelineno-10-3)  RecurrenceFrequency,
[](#%5F%5Fcodelineno-10-4)  Weekday,
[](#%5F%5Fcodelineno-10-5)} from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-10-6)
[](#%5F%5Fcodelineno-10-7)const createRecurringEvent = async () => {
[](#%5F%5Fcodelineno-10-8)  const { id } = await Calendar.createEvent({
[](#%5F%5Fcodelineno-10-9)    event: {
[](#%5F%5Fcodelineno-10-10)      title: 'Team stand-up',
[](#%5F%5Fcodelineno-10-11)      startDate: new Date('2026-09-01T09:00:00').getTime(),
[](#%5F%5Fcodelineno-10-12)      recurrence: {
[](#%5F%5Fcodelineno-10-13)        frequency: RecurrenceFrequency.Weekly,
[](#%5F%5Fcodelineno-10-14)        interval: 1,
[](#%5F%5Fcodelineno-10-15)        count: 10,
[](#%5F%5Fcodelineno-10-16)        daysOfWeek: [Weekday.Monday, Weekday.Wednesday],
[](#%5F%5Fcodelineno-10-17)      },
[](#%5F%5Fcodelineno-10-18)    },
[](#%5F%5Fcodelineno-10-19)  });
[](#%5F%5Fcodelineno-10-20)  return id;
[](#%5F%5Fcodelineno-10-21)};
`

### Get the events in a range[¶](#get-the-events-in-a-range "Permanent link")

Query all events that overlap a time range with `getEvents(...)`. Recurring events are expanded, so each occurrence is returned as a separate entry with its own `startDate`. Pass a `calendarId` to restrict the query to a single calendar:

`[](#%5F%5Fcodelineno-11-1)import { Calendar } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-11-2)
[](#%5F%5Fcodelineno-11-3)const getEventsOfNextWeek = async () => {
[](#%5F%5Fcodelineno-11-4)  const from = Date.now();
[](#%5F%5Fcodelineno-11-5)  const to = from + 7 * 24 * 60 * 60 * 1000;
[](#%5F%5Fcodelineno-11-6)  const { events } = await Calendar.getEvents({ from, to });
[](#%5F%5Fcodelineno-11-7)  return events;
[](#%5F%5Fcodelineno-11-8)};
`

A single event can be retrieved by its identifier with `getEventById(...)`, which resolves with `null` if the event does not exist:

`[](#%5F%5Fcodelineno-12-1)import { Calendar } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-12-2)
[](#%5F%5Fcodelineno-12-3)const getEventById = async (id: string) => {
[](#%5F%5Fcodelineno-12-4)  const { event } = await Calendar.getEventById({ id });
[](#%5F%5Fcodelineno-12-5)  return event;
[](#%5F%5Fcodelineno-12-6)};
`

### Update an event[¶](#update-an-event "Permanent link")

Update an event with `updateEventById(...)`. Only the properties that you pass are changed, all others keep their current values. Setting a property to `null` (or an array property to `[]`) removes it from the event:

`[](#%5F%5Fcodelineno-13-1)import { Calendar } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-13-2)
[](#%5F%5Fcodelineno-13-3)const rescheduleEvent = async (id: string, startDate: number) => {
[](#%5F%5Fcodelineno-13-4)  await Calendar.updateEventById({
[](#%5F%5Fcodelineno-13-5)    id,
[](#%5F%5Fcodelineno-13-6)    event: {
[](#%5F%5Fcodelineno-13-7)      startDate,
[](#%5F%5Fcodelineno-13-8)      endDate: startDate + 30 * 60 * 1000,
[](#%5F%5Fcodelineno-13-9)    },
[](#%5F%5Fcodelineno-13-10)  });
[](#%5F%5Fcodelineno-13-11)};
[](#%5F%5Fcodelineno-13-12)
[](#%5F%5Fcodelineno-13-13)const clearEventDetails = async (id: string) => {
[](#%5F%5Fcodelineno-13-14)  await Calendar.updateEventById({
[](#%5F%5Fcodelineno-13-15)    id,
[](#%5F%5Fcodelineno-13-16)    event: {
[](#%5F%5Fcodelineno-13-17)      location: null,
[](#%5F%5Fcodelineno-13-18)      description: null,
[](#%5F%5Fcodelineno-13-19)      alerts: [],
[](#%5F%5Fcodelineno-13-20)    },
[](#%5F%5Fcodelineno-13-21)  });
[](#%5F%5Fcodelineno-13-22)};
`

### Delete a single occurrence[¶](#delete-a-single-occurrence "Permanent link")

Pass the `instanceStartDate` of an occurrence, as returned by `getEvents(...)`, to apply an operation to a single occurrence of a recurring event instead of the whole series. The `span` option controls whether the operation affects only that occurrence or the occurrence and all future ones:

`[](#%5F%5Fcodelineno-14-1)import { Calendar, EventSpan } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-14-2)
[](#%5F%5Fcodelineno-14-3)const deleteOccurrence = async (id: string, instanceStartDate: number) => {
[](#%5F%5Fcodelineno-14-4)  await Calendar.deleteEventById({
[](#%5F%5Fcodelineno-14-5)    id,
[](#%5F%5Fcodelineno-14-6)    instanceStartDate,
[](#%5F%5Fcodelineno-14-7)    span: EventSpan.ThisEvent,
[](#%5F%5Fcodelineno-14-8)  });
[](#%5F%5Fcodelineno-14-9)};
[](#%5F%5Fcodelineno-14-10)
[](#%5F%5Fcodelineno-14-11)const deleteAllFutureOccurrences = async (
[](#%5F%5Fcodelineno-14-12)  id: string,
[](#%5F%5Fcodelineno-14-13)  instanceStartDate: number,
[](#%5F%5Fcodelineno-14-14)) => {
[](#%5F%5Fcodelineno-14-15)  await Calendar.deleteEventById({
[](#%5F%5Fcodelineno-14-16)    id,
[](#%5F%5Fcodelineno-14-17)    instanceStartDate,
[](#%5F%5Fcodelineno-14-18)    span: EventSpan.ThisAndFutureEvents,
[](#%5F%5Fcodelineno-14-19)  });
[](#%5F%5Fcodelineno-14-20)};
`

Without `instanceStartDate`, the entire recurring event is deleted.

### Display the system event dialog[¶](#display-the-system-event-dialog "Permanent link")

Let the user create an event in the system dialog with `displayCreateEvent(...)`, optionally prefilled with your event data. On iOS, the identifier of the created event is returned if the user saved the event:

`[](#%5F%5Fcodelineno-15-1)import { Calendar } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-15-2)
[](#%5F%5Fcodelineno-15-3)const displayCreateEvent = async () => {
[](#%5F%5Fcodelineno-15-4)  const { id } = await Calendar.displayCreateEvent({
[](#%5F%5Fcodelineno-15-5)    event: {
[](#%5F%5Fcodelineno-15-6)      title: 'Lunch with Jane',
[](#%5F%5Fcodelineno-15-7)      startDate: new Date('2026-09-01T12:00:00').getTime(),
[](#%5F%5Fcodelineno-15-8)      location: 'Main Street 1, Springfield',
[](#%5F%5Fcodelineno-15-9)    },
[](#%5F%5Fcodelineno-15-10)  });
[](#%5F%5Fcodelineno-15-11)  return id;
[](#%5F%5Fcodelineno-15-12)};
`

Use `displayUpdateEventById(...)` to let the user edit an existing event. On iOS, the `action` describes what the user did in the dialog:

`[](#%5F%5Fcodelineno-16-1)import { Calendar } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-16-2)
[](#%5F%5Fcodelineno-16-3)const displayUpdateEventById = async (id: string) => {
[](#%5F%5Fcodelineno-16-4)  const { action } = await Calendar.displayUpdateEventById({ id });
[](#%5F%5Fcodelineno-16-5)  return action;
[](#%5F%5Fcodelineno-16-6)};
`

The system dialogs on Android do not report a result back to the app, so `id` and `action` are only available on iOS. On Android, only the event properties that are supported by the system intent are prefilled, and the remaining properties are silently ignored.

### Listen for calendar changes[¶](#listen-for-calendar-changes "Permanent link")

Register a listener for the `calendarChange` event to reload your data whenever calendars or events change, including changes that were made in the calendar app or by other apps. The event carries no payload, because the operating systems do not report which entities changed:

`[](#%5F%5Fcodelineno-17-1)import { Calendar } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-17-2)
[](#%5F%5Fcodelineno-17-3)const addCalendarChangeListener = async () => {
[](#%5F%5Fcodelineno-17-4)  return Calendar.addListener('calendarChange', () => {
[](#%5F%5Fcodelineno-17-5)    console.log('The calendars or events on the device have changed.');
[](#%5F%5Fcodelineno-17-6)  });
[](#%5F%5Fcodelineno-17-7)};
[](#%5F%5Fcodelineno-17-8)
[](#%5F%5Fcodelineno-17-9)const removeAllListeners = async () => {
[](#%5F%5Fcodelineno-17-10)  await Calendar.removeAllListeners();
[](#%5F%5Fcodelineno-17-11)};
`

### Open the calendar app and the app settings[¶](#open-the-calendar-app-and-the-app-settings "Permanent link")

Open the calendar app of the device at a specific date with `openCalendar(...)`, for example after an event was created. Use `openSettings()` to send the user to the settings of your app so that a previously denied permission can be granted:

`[](#%5F%5Fcodelineno-18-1)import { Calendar } from '@capawesome-team/capacitor-calendar';
[](#%5F%5Fcodelineno-18-2)
[](#%5F%5Fcodelineno-18-3)const openCalendar = async (date: number) => {
[](#%5F%5Fcodelineno-18-4)  await Calendar.openCalendar({ date });
[](#%5F%5Fcodelineno-18-5)};
[](#%5F%5Fcodelineno-18-6)
[](#%5F%5Fcodelineno-18-7)const openSettings = async () => {
[](#%5F%5Fcodelineno-18-8)  await Calendar.openSettings();
[](#%5F%5Fcodelineno-18-9)};
`

## API[¶](#api "Permanent link")

* [checkPermissions()](#checkpermissions)
* [createCalendar(...)](#createcalendar)
* [createEvent(...)](#createevent)
* [deleteCalendarById(...)](#deletecalendarbyid)
* [deleteEventById(...)](#deleteeventbyid)
* [displayCreateEvent(...)](#displaycreateevent)
* [displayUpdateEventById(...)](#displayupdateeventbyid)
* [getCalendars()](#getcalendars)
* [getDefaultCalendar()](#getdefaultcalendar)
* [getEventById(...)](#geteventbyid)
* [getEvents(...)](#getevents)
* [openCalendar(...)](#opencalendar)
* [openSettings()](#opensettings)
* [requestPermissions(...)](#requestpermissions)
* [updateEventById(...)](#updateeventbyid)
* [addListener('calendarChange', ...)](#addlistenercalendarchange-)
* [removeAllListeners()](#removealllisteners)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)
* [Enums](#enums)

### checkPermissions()[¶](#checkpermissions "Permanent link")

`[](#%5F%5Fcodelineno-19-1)checkPermissions() => Promise<PermissionStatus>
`

Check permissions to access the device calendar.

Only available on Android and iOS.

**Returns:** `Promise<[PermissionStatus](#permissionstatus)>`

**Since:** 0.0.1

---

### createCalendar(...)[¶](#createcalendar "Permanent link")

`[](#%5F%5Fcodelineno-20-1)createCalendar(options: CreateCalendarOptions) => Promise<CreateCalendarResult>
`

Create a new calendar on the device.

Only available on Android and iOS.

| Param       | Type                                            |
| ----------- | ----------------------------------------------- |
| **options** | [CreateCalendarOptions](#createcalendaroptions) |

**Returns:** `Promise<[CreateCalendarResult](#createcalendarresult)>`

**Since:** 0.0.1

---

### createEvent(...)[¶](#createevent "Permanent link")

`[](#%5F%5Fcodelineno-21-1)createEvent(options: CreateEventOptions) => Promise<CreateEventResult>
`

Create a new event in a calendar.

Only available on Android and iOS.

| Param       | Type                                      |
| ----------- | ----------------------------------------- |
| **options** | [CreateEventOptions](#createeventoptions) |

**Returns:** `Promise<[CreateEventResult](#createeventresult)>`

**Since:** 0.0.1

---

### deleteCalendarById(...)[¶](#deletecalendarbyid "Permanent link")

`[](#%5F%5Fcodelineno-22-1)deleteCalendarById(options: DeleteCalendarByIdOptions) => Promise<void>
`

Delete a calendar from the device.

Only available on Android and iOS.

| Param       | Type                                                    |
| ----------- | ------------------------------------------------------- |
| **options** | [DeleteCalendarByIdOptions](#deletecalendarbyidoptions) |

**Since:** 0.0.1

---

### deleteEventById(...)[¶](#deleteeventbyid "Permanent link")

`[](#%5F%5Fcodelineno-23-1)deleteEventById(options: DeleteEventByIdOptions) => Promise<void>
`

Delete an event from the device.

Only available on Android and iOS.

| Param       | Type                                              |
| ----------- | ------------------------------------------------- |
| **options** | [DeleteEventByIdOptions](#deleteeventbyidoptions) |

**Since:** 0.0.1

---

### displayCreateEvent(...)[¶](#displaycreateevent "Permanent link")

`[](#%5F%5Fcodelineno-24-1)displayCreateEvent(options?: DisplayCreateEventOptions | undefined) => Promise<DisplayCreateEventResult>
`

Display the system user interface to create a new event.

Only available on Android and iOS.

| Param       | Type                                                    |
| ----------- | ------------------------------------------------------- |
| **options** | [DisplayCreateEventOptions](#displaycreateeventoptions) |

**Returns:** `Promise<[DisplayCreateEventResult](#displaycreateeventresult)>`

**Since:** 0.0.1

---

### displayUpdateEventById(...)[¶](#displayupdateeventbyid "Permanent link")

`[](#%5F%5Fcodelineno-25-1)displayUpdateEventById(options: DisplayUpdateEventByIdOptions) => Promise<DisplayUpdateEventByIdResult>
`

Display the system user interface to update an existing event.

Only available on Android and iOS.

| Param       | Type                                                            |
| ----------- | --------------------------------------------------------------- |
| **options** | [DisplayUpdateEventByIdOptions](#displayupdateeventbyidoptions) |

**Returns:** `Promise<[DisplayUpdateEventByIdResult](#displayupdateeventbyidresult)>`

**Since:** 0.0.1

---

### getCalendars()[¶](#getcalendars "Permanent link")

`[](#%5F%5Fcodelineno-26-1)getCalendars() => Promise<GetCalendarsResult>
`

Get all calendars on the device.

Only available on Android and iOS.

**Returns:** `Promise<[GetCalendarsResult](#getcalendarsresult)>`

**Since:** 0.0.1

---

### getDefaultCalendar()[¶](#getdefaultcalendar "Permanent link")

`[](#%5F%5Fcodelineno-27-1)getDefaultCalendar() => Promise<GetDefaultCalendarResult>
`

Get the default calendar for new events.

Only available on Android and iOS.

**Returns:** `Promise<[GetDefaultCalendarResult](#getdefaultcalendarresult)>`

**Since:** 0.0.1

---

### getEventById(...)[¶](#geteventbyid "Permanent link")

`[](#%5F%5Fcodelineno-28-1)getEventById(options: GetEventByIdOptions) => Promise<GetEventByIdResult>
`

Get a single event by its identifier.

Only available on Android and iOS.

| Param       | Type                                        |
| ----------- | ------------------------------------------- |
| **options** | [GetEventByIdOptions](#geteventbyidoptions) |

**Returns:** `Promise<[GetEventByIdResult](#geteventbyidresult)>`

**Since:** 0.0.1

---

### getEvents(...)[¶](#getevents "Permanent link")

`[](#%5F%5Fcodelineno-29-1)getEvents(options: GetEventsOptions) => Promise<GetEventsResult>
`

Get the events in a given time range.

Returns all events that overlap the time range, including single occurrences of recurring events.

Rejects with the error code `CALENDAR_NOT_FOUND` if a `calendarId` is provided but no calendar with that identifier exists.

Only available on Android and iOS.

| Param       | Type                                  |
| ----------- | ------------------------------------- |
| **options** | [GetEventsOptions](#geteventsoptions) |

**Returns:** `Promise<[GetEventsResult](#geteventsresult)>`

**Since:** 0.0.1

---

### openCalendar(...)[¶](#opencalendar "Permanent link")

`[](#%5F%5Fcodelineno-30-1)openCalendar(options?: OpenCalendarOptions | undefined) => Promise<void>
`

Open the calendar app of the device.

Only available on Android and iOS.

| Param       | Type                                        |
| ----------- | ------------------------------------------- |
| **options** | [OpenCalendarOptions](#opencalendaroptions) |

**Since:** 0.0.1

---

### openSettings()[¶](#opensettings "Permanent link")

`[](#%5F%5Fcodelineno-31-1)openSettings() => Promise<void>
`

Open the settings of the app so that the user can grant or revoke permissions.

Only available on Android and iOS.

**Since:** 0.0.1

---

### requestPermissions(...)[¶](#requestpermissions "Permanent link")

`[](#%5F%5Fcodelineno-32-1)requestPermissions(options?: RequestPermissionsOptions | undefined) => Promise<PermissionStatus>
`

Request permissions to access the device calendar.

On iOS 17+, requesting only the `writeCalendar` permission requests write-only access. Requesting the `readCalendar` permission requests full access.

Only available on Android and iOS.

| Param       | Type                                                    |
| ----------- | ------------------------------------------------------- |
| **options** | [RequestPermissionsOptions](#requestpermissionsoptions) |

**Returns:** `Promise<[PermissionStatus](#permissionstatus)>`

**Since:** 0.0.1

---

### updateEventById(...)[¶](#updateeventbyid "Permanent link")

`[](#%5F%5Fcodelineno-33-1)updateEventById(options: UpdateEventByIdOptions) => Promise<void>
`

Update an existing event.

Only available on Android and iOS.

| Param       | Type                                              |
| ----------- | ------------------------------------------------- |
| **options** | [UpdateEventByIdOptions](#updateeventbyidoptions) |

**Since:** 0.0.1

---

### addListener('calendarChange', ...)[¶](#addlistenercalendarchange "Permanent link")

`[](#%5F%5Fcodelineno-34-1)addListener(eventName: 'calendarChange', listenerFunc: () => void) => Promise<PluginListenerHandle>
`

Called when calendars or events are created, updated or deleted, including by other apps.

Only available on Android and iOS.

| Param            | Type             |
| ---------------- | ---------------- |
| **eventName**    | 'calendarChange' |
| **listenerFunc** | () => void       |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.0.1

---

### removeAllListeners()[¶](#removealllisteners "Permanent link")

`[](#%5F%5Fcodelineno-35-1)removeAllListeners() => Promise<void>
`

Remove all listeners for this plugin.

**Since:** 0.0.1

---

### Interfaces[¶](#interfaces "Permanent link")

#### PermissionStatus[¶](#permissionstatus "Permanent link")

| Prop              | Type                                | Description                                                                                                                | Since |
| ----------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----- |
| **readCalendar**  | [PermissionState](#permissionstate) | The permission state for reading calendar data. On iOS, this is prompt as long as only write-only access has been granted. | 0.0.1 |
| **writeCalendar** | [PermissionState](#permissionstate) | The permission state for writing calendar data.                                                                            | 0.0.1 |

#### CreateCalendarResult[¶](#createcalendarresult "Permanent link")

| Prop   | Type   | Description                             | Since |
| ------ | ------ | --------------------------------------- | ----- |
| **id** | string | The identifier of the created calendar. | 0.0.1 |

#### CreateCalendarOptions[¶](#createcalendaroptions "Permanent link")

| Prop      | Type   | Description                                                      | Since |
| --------- | ------ | ---------------------------------------------------------------- | ----- |
| **color** | string | The color of the calendar as a hex string in the format #RRGGBB. | 0.0.1 |
| **title** | string | The title of the calendar.                                       | 0.0.1 |

#### CreateEventResult[¶](#createeventresult "Permanent link")

| Prop   | Type   | Description                          | Since |
| ------ | ------ | ------------------------------------ | ----- |
| **id** | string | The identifier of the created event. | 0.0.1 |

#### CreateEventOptions[¶](#createeventoptions "Permanent link")

| Prop      | Type                      | Description          | Since |
| --------- | ------------------------- | -------------------- | ----- |
| **event** | [EventInput](#eventinput) | The event to create. | 0.0.1 |

#### EventInput[¶](#eventinput "Permanent link")

| Prop             | Type                                    | Description                                                                                                                                                                                                                                                                 | Default                                 | Since |
| ---------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ----- |
| **alerts**       | number\[\]                              | The alerts of the event as offsets in minutes before the start of the event. Negative values represent minutes after the start.                                                                                                                                             |                                         | 0.0.1 |
| **allDay**       | boolean                                 | Whether the event is an all-day event. For all-day events, startDate and endDate are interpreted as midnight UTC of the respective calendar day.                                                                                                                            | false                                   | 0.0.1 |
| **availability** | [EventAvailability](#eventavailability) | The availability of the event.                                                                                                                                                                                                                                              |                                         | 0.0.1 |
| **calendarId**   | string                                  | The identifier of the calendar in which the event is created.                                                                                                                                                                                                               | The identifier of the default calendar. | 0.0.1 |
| **description**  | string                                  | The description of the event.                                                                                                                                                                                                                                               |                                         | 0.0.1 |
| **endDate**      | number                                  | The end date of the event as a timestamp in milliseconds. If not provided, the event ends one hour after startDate (all-day events: on the same day as startDate). For all-day events, the end date is exclusive (midnight UTC of the day after the last day of the event). |                                         | 0.0.1 |
| **location**     | string                                  | The location of the event.                                                                                                                                                                                                                                                  |                                         | 0.0.1 |
| **recurrence**   | [RecurrenceRule](#recurrencerule)       | The recurrence rule of the event.                                                                                                                                                                                                                                           |                                         | 0.0.1 |
| **startDate**    | number                                  | The start date of the event as a timestamp in milliseconds.                                                                                                                                                                                                                 |                                         | 0.0.1 |
| **timezone**     | string                                  | The time zone of the event as an IANA time zone identifier.                                                                                                                                                                                                                 | The default time zone of the device.    | 0.0.1 |
| **title**        | string                                  | The title of the event.                                                                                                                                                                                                                                                     |                                         | 0.0.1 |

#### RecurrenceRule[¶](#recurrencerule "Permanent link")

| Prop           | Type                                        | Description                                                                                                                                                | Default | Since |
| -------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----- |
| **count**      | number                                      | The number of occurrences after which the recurrence ends. Takes precedence over until.                                                                    |         | 0.0.1 |
| **daysOfWeek** | Weekday\[\]                                 | The days of the week on which the event recurs.                                                                                                            |         | 0.0.1 |
| **frequency**  | [RecurrenceFrequency](#recurrencefrequency) | The frequency of the recurrence.                                                                                                                           |         | 0.0.1 |
| **interval**   | number                                      | The interval between occurrences of the recurrence. For example, an interval of 2 with a Weekly frequency results in an event that recurs every two weeks. | 1       | 0.0.1 |
| **until**      | number                                      | The date on which the recurrence ends as a timestamp in milliseconds.                                                                                      |         | 0.0.1 |

#### DeleteCalendarByIdOptions[¶](#deletecalendarbyidoptions "Permanent link")

| Prop   | Type   | Description                               | Since |
| ------ | ------ | ----------------------------------------- | ----- |
| **id** | string | The identifier of the calendar to delete. | 0.0.1 |

#### DeleteEventByIdOptions[¶](#deleteeventbyidoptions "Permanent link")

| Prop                  | Type                    | Description                                                                                                                                                                                                                                                                                                          | Default             | Since |
| --------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ----- |
| **id**                | string                  | The identifier of the event to delete.                                                                                                                                                                                                                                                                               |                     | 0.0.1 |
| **instanceStartDate** | number                  | The start date of a single occurrence of a recurring event as a timestamp in milliseconds, as returned by getEvents(...). If provided, only the given occurrence (or, depending on span, the given and all future occurrences) of the recurring event is deleted. If omitted, the entire recurring event is deleted. |                     | 0.0.1 |
| **span**              | [EventSpan](#eventspan) | The span of a recurring event to which the operation is applied. Only applied when instanceStartDate is provided.                                                                                                                                                                                                    | EventSpan.ThisEvent | 0.0.1 |

#### DisplayCreateEventResult[¶](#displaycreateeventresult "Permanent link")

| Prop   | Type   | Description                                                                                       | Since |
| ------ | ------ | ------------------------------------------------------------------------------------------------- | ----- |
| **id** | string | The identifier of the created event. Only returned if the event was saved. Only available on iOS. | 0.0.1 |

#### DisplayCreateEventOptions[¶](#displaycreateeventoptions "Permanent link")

| Prop      | Type                                | Description                                                                                                                                                                 | Since |
| --------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **event** | Partial<[EventInput](#eventinput)\> | The event data with which the dialog is prefilled. On Android, only the properties supported by the system intent are applied. Unsupported properties are silently ignored. | 0.0.1 |

#### DisplayUpdateEventByIdResult[¶](#displayupdateeventbyidresult "Permanent link")

| Prop       | Type                                | Description                                                              | Since |
| ---------- | ----------------------------------- | ------------------------------------------------------------------------ | ----- |
| **action** | [EventEditAction](#eventeditaction) | The action that the user performed in the dialog. Only available on iOS. | 0.0.1 |

#### DisplayUpdateEventByIdOptions[¶](#displayupdateeventbyidoptions "Permanent link")

| Prop   | Type   | Description                            | Since |
| ------ | ------ | -------------------------------------- | ----- |
| **id** | string | The identifier of the event to update. | 0.0.1 |

#### GetCalendarsResult[¶](#getcalendarsresult "Permanent link")

| Prop          | Type         | Description                  | Since |
| ------------- | ------------ | ---------------------------- | ----- |
| **calendars** | Calendar\[\] | The calendars on the device. | 0.0.1 |

#### Calendar[¶](#calendar "Permanent link")

| Prop         | Type    | Description                                                        | Since |
| ------------ | ------- | ------------------------------------------------------------------ | ----- |
| **color**    | string  | The color of the calendar as a hex string in the format #RRGGBB.   | 0.0.1 |
| **id**       | string  | The identifier of the calendar.                                    | 0.0.1 |
| **title**    | string  | The title of the calendar.                                         | 0.0.1 |
| **writable** | boolean | Whether events can be added, updated, or deleted in this calendar. | 0.0.1 |

#### GetDefaultCalendarResult[¶](#getdefaultcalendarresult "Permanent link")

| Prop         | Type                          | Description                                                                                 | Since |
| ------------ | ----------------------------- | ------------------------------------------------------------------------------------------- | ----- |
| **calendar** | [Calendar](#calendar) \| null | The default calendar for new events. If no default calendar is available, null is returned. | 0.0.1 |

#### GetEventByIdResult[¶](#geteventbyidresult "Permanent link")

| Prop      | Type                                    | Description                                                                   | Since |
| --------- | --------------------------------------- | ----------------------------------------------------------------------------- | ----- |
| **event** | [CalendarEvent](#calendarevent) \| null | The event with the given identifier. If no event was found, null is returned. | 0.0.1 |

#### CalendarEvent[¶](#calendarevent "Permanent link")

| Prop             | Type                                    | Description                                                                                                                                                        | Since |
| ---------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- |
| **alerts**       | number\[\]                              | The alerts of the event as offsets in minutes before the start of the event. Negative values represent minutes after the start.                                    | 0.0.1 |
| **allDay**       | boolean                                 | Whether the event is an all-day event. For all-day events, startDate and endDate are returned as midnight UTC of the respective calendar day.                      | 0.0.1 |
| **availability** | [EventAvailability](#eventavailability) | The availability of the event.                                                                                                                                     | 0.0.1 |
| **calendarId**   | string                                  | The identifier of the calendar that the event belongs to.                                                                                                          | 0.0.1 |
| **description**  | string                                  | The description of the event.                                                                                                                                      | 0.0.1 |
| **endDate**      | number                                  | The end date of the event as a timestamp in milliseconds. For all-day events, the end date is exclusive (midnight UTC of the day after the last day of the event). | 0.0.1 |
| **id**           | string                                  | The identifier of the event. All occurrences of a recurring event share the same identifier.                                                                       | 0.0.1 |
| **location**     | string                                  | The location of the event.                                                                                                                                         | 0.0.1 |
| **recurrence**   | [RecurrenceRule](#recurrencerule)       | The recurrence rule of the event.                                                                                                                                  | 0.0.1 |
| **startDate**    | number                                  | The start date of the event as a timestamp in milliseconds.                                                                                                        | 0.0.1 |
| **status**       | [EventStatus](#eventstatus)             | The confirmation status of the event.                                                                                                                              | 0.0.1 |
| **timezone**     | string                                  | The time zone of the event as an IANA time zone identifier.                                                                                                        | 0.0.1 |
| **title**        | string                                  | The title of the event.                                                                                                                                            | 0.0.1 |

#### GetEventByIdOptions[¶](#geteventbyidoptions "Permanent link")

| Prop   | Type   | Description                  | Since |
| ------ | ------ | ---------------------------- | ----- |
| **id** | string | The identifier of the event. | 0.0.1 |

#### GetEventsResult[¶](#geteventsresult "Permanent link")

| Prop       | Type              | Description                         | Since |
| ---------- | ----------------- | ----------------------------------- | ----- |
| **events** | CalendarEvent\[\] | The events in the given time range. | 0.0.1 |

#### GetEventsOptions[¶](#geteventsoptions "Permanent link")

| Prop           | Type   | Description                                                                                                       | Since |
| -------------- | ------ | ----------------------------------------------------------------------------------------------------------------- | ----- |
| **calendarId** | string | The identifier of the calendar to get the events from. If not provided, the events of all calendars are returned. | 0.0.1 |
| **from**       | number | The start of the time range as a timestamp in milliseconds.                                                       | 0.0.1 |
| **to**         | number | The end of the time range as a timestamp in milliseconds.                                                         | 0.0.1 |

#### OpenCalendarOptions[¶](#opencalendaroptions "Permanent link")

| Prop     | Type   | Description                                                                  | Default           | Since |
| -------- | ------ | ---------------------------------------------------------------------------- | ----------------- | ----- |
| **date** | number | The date to which the calendar app is opened as a timestamp in milliseconds. | The current time. | 0.0.1 |

#### RequestPermissionsOptions[¶](#requestpermissionsoptions "Permanent link")

| Prop            | Type                       | Description                 | Default                             | Since |
| --------------- | -------------------------- | --------------------------- | ----------------------------------- | ----- |
| **permissions** | CalendarPermissionType\[\] | The permissions to request. | \['readCalendar', 'writeCalendar'\] | 0.0.1 |

#### UpdateEventByIdOptions[¶](#updateeventbyidoptions "Permanent link")

| Prop                  | Type                                                       | Description                                                                                                                                                                                                                                                                                                          | Default             | Since |
| --------------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ----- |
| **event**             | [Nullable](#nullable)<Partial<[EventInput](#eventinput)\>> | The updated event data. Missing properties are ignored and keep their existing values. Properties explicitly set to null (or empty arrays \[\]) will be removed from the event. Properties that are required for the event structure (allDay, calendarId, endDate, startDate, timezone) must not be set to null.     |                     | 0.0.1 |
| **id**                | string                                                     | The identifier of the event to update.                                                                                                                                                                                                                                                                               |                     | 0.0.1 |
| **instanceStartDate** | number                                                     | The start date of a single occurrence of a recurring event as a timestamp in milliseconds, as returned by getEvents(...). If provided, only the given occurrence (or, depending on span, the given and all future occurrences) of the recurring event is updated. If omitted, the entire recurring event is updated. |                     | 0.0.1 |
| **span**              | [EventSpan](#eventspan)                                    | The span of a recurring event to which the operation is applied. Only applied when instanceStartDate is provided.                                                                                                                                                                                                    | EventSpan.ThisEvent | 0.0.1 |

#### PluginListenerHandle[¶](#pluginlistenerhandle "Permanent link")

| Prop       | Type                |
| ---------- | ------------------- |
| **remove** | () => Promise<void> |

### Type Aliases[¶](#type-aliases "Permanent link")

#### PermissionState[¶](#permissionstate "Permanent link")

`'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'`

#### EventEditAction[¶](#eventeditaction "Permanent link")

The action that the user performed in a system event dialog.

`'canceled' | 'deleted' | 'saved'`

#### EventStatus[¶](#eventstatus "Permanent link")

The confirmation status of an event.

`'canceled' | 'confirmed' | 'tentative'`

#### CalendarPermissionType[¶](#calendarpermissiontype "Permanent link")

The permissions to request when calling `requestPermissions(...)`.

`'readCalendar' | 'writeCalendar'`

#### Nullable[¶](#nullable "Permanent link")

`{ [K in keyof T]: T[K] | null }`

### Enums[¶](#enums "Permanent link")

#### EventAvailability[¶](#eventavailability "Permanent link")

| Members         | Value         | Description                                                                               | Since |
| --------------- | ------------- | ----------------------------------------------------------------------------------------- | ----- |
| **Busy**        | 'BUSY'        | The time of the event is marked as busy.                                                  | 0.0.1 |
| **Free**        | 'FREE'        | The time of the event is marked as free.                                                  | 0.0.1 |
| **Tentative**   | 'TENTATIVE'   | The time of the event is marked as tentative.                                             | 0.0.1 |
| **Unavailable** | 'UNAVAILABLE' | The time of the event is marked as unavailable. On Android, this value is mapped to Busy. | 0.0.1 |

#### Weekday[¶](#weekday "Permanent link")

| Members       | Value       | Description                     | Since |
| ------------- | ----------- | ------------------------------- | ----- |
| **Friday**    | 'FRIDAY'    | The event recurs on Fridays.    | 0.0.1 |
| **Monday**    | 'MONDAY'    | The event recurs on Mondays.    | 0.0.1 |
| **Saturday**  | 'SATURDAY'  | The event recurs on Saturdays.  | 0.0.1 |
| **Sunday**    | 'SUNDAY'    | The event recurs on Sundays.    | 0.0.1 |
| **Thursday**  | 'THURSDAY'  | The event recurs on Thursdays.  | 0.0.1 |
| **Tuesday**   | 'TUESDAY'   | The event recurs on Tuesdays.   | 0.0.1 |
| **Wednesday** | 'WEDNESDAY' | The event recurs on Wednesdays. | 0.0.1 |

#### RecurrenceFrequency[¶](#recurrencefrequency "Permanent link")

| Members     | Value     | Description               | Since |
| ----------- | --------- | ------------------------- | ----- |
| **Daily**   | 'DAILY'   | The event recurs daily.   | 0.0.1 |
| **Monthly** | 'MONTHLY' | The event recurs monthly. | 0.0.1 |
| **Weekly**  | 'WEEKLY'  | The event recurs weekly.  | 0.0.1 |
| **Yearly**  | 'YEARLY'  | The event recurs yearly.  | 0.0.1 |

#### EventSpan[¶](#eventspan "Permanent link")

| Members                 | Value                       | Description                                                                                         | Since |
| ----------------------- | --------------------------- | --------------------------------------------------------------------------------------------------- | ----- |
| **ThisAndFutureEvents** | 'THIS\_AND\_FUTURE\_EVENTS' | The operation is applied to the given occurrence and all future occurrences of the recurring event. | 0.0.1 |
| **ThisEvent**           | 'THIS\_EVENT'               | The operation is applied only to the given occurrence of the recurring event.                       | 0.0.1 |

## Recurring Events[¶](#recurring-events "Permanent link")

Recurring events are stored as a single event with a recurrence rule, but they are displayed to the user as many occurrences. The plugin makes both views available and keeps them consistent across Android and iOS.

**Occurrence expansion**: `getEvents(...)` expands recurring events into their occurrences. Each occurrence is returned as a separate entry whose `startDate` and `endDate` describe that occurrence, while the `id` and the `recurrence` rule are the same for all occurrences of the same series. `getEventById(...)`, in contrast, always returns the series itself with its original start date.

**Targeting a single occurrence**: `updateEventById(...)` and `deleteEventById(...)` operate on the whole series by default. Pass the `startDate` of an occurrence as `instanceStartDate` to target that occurrence instead, and use `span` to choose the scope:

* `EventSpan.ThisEvent` (default) applies the change to the given occurrence only. The rest of the series remains untouched.
* `EventSpan.ThisAndFutureEvents` applies the change to the given occurrence and all following ones, while past occurrences remain untouched.

**Reading a rule back**: the `recurrence` property of an event is both written and read. A rule that uses parts which are not supported by the plugin — for example a rule created in another app — is read back as the closest supported subset, so `frequency` and `interval` are always correct even if a more exotic part is dropped.

**All-day events and time zones**: an event with `allDay: true` has no time of day. Its `startDate` and `endDate` are therefore interpreted and returned as **midnight UTC** of the respective calendar day on both platforms, independent of the time zone of the device. The `endDate` is **exclusive**: it is midnight UTC of the day after the last day of the event, so a one-day all-day event on `2026-09-01` has `startDate = Date.UTC(2026, 8, 1)` and `endDate = Date.UTC(2026, 8, 2)`. An `endDate` that is missing or not on a midnight boundary is normalized: it is floored to midnight UTC of its day and raised to at least one day after `startDate`, so the event always spans at least one full day. Build these timestamps in UTC, for example with `Date.UTC(2026, 8, 1)`, and format them in UTC as well — using the local time zone instead is what makes an all-day event appear on the wrong day. For events that are not all-day, the `timezone` property defines the time zone in which the event takes place and defaults to the time zone of the device.

## FAQ[¶](#faq "Permanent link")

### How is this plugin different from other similar plugins?[¶](#how-is-this-plugin-different-from-other-similar-plugins "Permanent link")

We focused on correctness instead of a long feature list. Every runtime failure rejects with a documented error code, so your app can react to a missing event or a read-only calendar programmatically. Recurrence rules can be read back, not just written, so a recurring event can round-trip through your app without losing information. Single occurrences of a recurring event can be updated and deleted, including all future occurrences. All-day events and time zones follow one documented contract on both platforms, and behavior that only one platform can provide is documented as such instead of being silently faked. On top of that, the plugin is covered by unit tests, is built from the ground up by the Capawesome Team, and comes with priority support.

### Can I use this plugin with Ionic, React, Vue or Angular?[¶](#can-i-use-this-plugin-with-ionic-react-vue-or-angular "Permanent link")

Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects.

## Related Plugins[¶](#related-plugins "Permanent link")

* [Contacts](https://capawesome.io/docs/sdks/capacitor/contacts/): Read and write device contacts, for example to invite them to an event.
* [Datetime Picker](https://capawesome.io/docs/sdks/capacitor/datetime-picker/): Let the user pick the date and time of an event natively.

## Newsletter[¶](#newsletter "Permanent link")

Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).

## Changelog[¶](#changelog "Permanent link")

See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/calendar/CHANGELOG.md).

## Breaking Changes[¶](#breaking-changes "Permanent link")

See [BREAKING.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/calendar/BREAKING.md).

## License[¶](#license "Permanent link")

See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/calendar/LICENSE).

August 15, 2026 

Back to top

```json
{"@context": "https://schema.org", "@graph": [{"@type": "TechArticle", "@id": "https://capawesome.io/docs/sdks/capacitor/calendar/#article", "headline": "Capacitor Calendar Plugin for Android & iOS", "name": "Capacitor Calendar Plugin for Android & iOS", "description": "Capacitor Calendar plugin to create, read, update, and delete calendars and events on Android and iOS, including recurring events and alerts.", "inLanguage": "en", "url": "https://capawesome.io/docs/sdks/capacitor/calendar/", "mainEntityOfPage": "https://capawesome.io/docs/sdks/capacitor/calendar/", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "about": {"@id": "https://capawesome.io/docs/sdks/capacitor/calendar/#software"}}, {"@type": "SoftwareSourceCode", "@id": "https://capawesome.io/docs/sdks/capacitor/calendar/#software", "name": "Capacitor Calendar Plugin for Android & iOS", "description": "Capacitor Calendar plugin to create, read, update, and delete calendars and events on Android and iOS, including recurring events and alerts.", "url": "https://capawesome.io/docs/sdks/capacitor/calendar/", "programmingLanguage": "TypeScript", "runtimePlatform": "Capacitor", "codeRepository": "https://github.com/capawesome-team", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}}]}
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "How is this plugin different from other similar plugins?", "acceptedAnswer": {"@type": "Answer", "text": "We focused on correctness instead of a long feature list. Every runtime failure rejects with a documented error code, so your app can react to a missing event or a read-only calendar programmatically. Recurrence rules can be read back, not just written, so a recurring event can round-trip through your app without losing information. Single occurrences of a recurring event can be updated and deleted, including all future occurrences. All-day events and time zones follow one documented contract on both platforms, and behavior that only one platform can provide is documented as such instead of being silently faked. On top of that, the plugin is covered by unit tests, is built from the ground up by the Capawesome Team, and comes with priority support."}}, {"@type": "Question", "name": "Can I use this plugin with Ionic, React, Vue or Angular?", "acceptedAnswer": {"@type": "Answer", "text": "Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects."}}], "url": "https://capawesome.io/docs/sdks/capacitor/calendar/"}
```
