← All @molecule/* packages · App templates
@molecule/app-device-calendarNative · native · App (browser) · v1.0.1 · Apache-2.0
Device/OS calendar access — read & write the user's real iOS/Android calendars (not the in-app calendar UI; that is @molecule/app-calendar)
npm install @molecule/app-device-calendar@molecule/app-device-calendar bridges the native core to the native platform layer of the app.
import {
createEvent,
getCalendars,
getEvents,
getPermissionStatus,
hasProvider,
requestPermission,
} from '@molecule/app-device-calendar'
async function addReminderToDeviceCalendar(): Promise<void> {
if (!hasProvider()) return // no provider wired — feature-gate the UI
if ((await getPermissionStatus()) !== 'granted') {
if ((await requestPermission()) !== 'granted') return
}
const writable = (await getCalendars()).find((c) => !c.readOnly)
if (!writable) return
await createEvent({
calendarId: writable.id,
title: 'Dentist',
startDate: '2026-08-01T09:00:00.000Z',
endDate: '2026-08-01T09:30:00.000Z',
allDay: false,
})
}Works with: @molecule/app-bond, @molecule/app-i18n
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Device calendar access interface for molecule.dev.
Framework-agnostic core for reading and writing events in the DEVICE's
calendar store (the user's actual iOS/Android calendars) through a
swappable CalendarProvider: list calendars, query/create/update/delete
events, open the native calendar app, and manage permissions. Also ships
pure helpers (eventsOverlap, getEventDuration, formatEventTimeRange,
parseQuickEvent).
NOT the same package as @molecule/app-calendar — that is the calendar
UI core (month/week/day views rendered inside your app). This package
talks to the operating system's calendar database. Pick by need: rendering
a calendar screen → app-calendar; syncing with the user's real calendars
→ app-device-calendar.
import {
createEvent,
getCalendars,
getEvents,
getPermissionStatus,
hasProvider,
requestPermission,
} from '@molecule/app-device-calendar'
async function addReminderToDeviceCalendar(): Promise<void> {
if (!hasProvider()) return // no provider wired — feature-gate the UI
if ((await getPermissionStatus()) !== 'granted') {
if ((await requestPermission()) !== 'granted') return
}
const writable = (await getCalendars()).find((c) => !c.readOnly)
if (!writable) return
await createEvent({
calendarId: writable.id,
title: 'Dentist',
startDate: '2026-08-01T09:00:00.000Z',
endDate: '2026-08-01T09:30:00.000Z',
allDay: false,
})
}
native
npm install @molecule/app-device-calendar @molecule/app-bond @molecule/app-i18n
CalendarDevice calendar metadata (ID, title, color, read-only flag, account, visibility).
interface Calendar {
/** Calendar ID */
id: string
/** Calendar title/name */
title: string
/** Calendar color */
color?: string
/** Whether calendar is read-only */
readOnly: boolean
/** Calendar type */
type: 'local' | 'subscription' | 'birthday' | 'exchange' | 'google' | 'other'
/** Account name */
accountName?: string
/** Whether calendar is visible */
visible: boolean
}
CalendarCapabilitiesCalendar capabilities
interface CalendarCapabilities {
/** Whether calendar access is supported */
supported: boolean
/** Whether reading is supported */
canRead: boolean
/** Whether writing is supported */
canWrite: boolean
/** Whether reminders are supported */
supportsReminders: boolean
/** Whether recurrence is supported */
supportsRecurrence: boolean
/** Whether attendees are supported */
supportsAttendees: boolean
}
CalendarEventFull calendar event with title, dates, location, attendees, reminders, and recurrence rules.
interface CalendarEvent {
/** Event ID */
id: string
/** Calendar ID */
calendarId: string
/** Event title */
title: string
/** Event description */
description?: string
/** Event location */
location?: string
/** Start date/time (ISO string) */
startDate: string
/** End date/time (ISO string) */
endDate: string
/** Whether event is all-day */
allDay: boolean
/** Event timezone */
timezone?: string
/** Event URL */
url?: string
/** Event notes */
notes?: string
/** Attendees */
attendees?: EventAttendee[]
/** Reminders */
reminders?: EventReminder[]
/** Recurrence rule */
recurrence?: RecurrenceRule
/** Event status */
status?: 'confirmed' | 'tentative' | 'cancelled'
/** Event availability */
availability?: 'busy' | 'free' | 'tentative'
/** Organizer info */
organizer?: EventAttendee
}
CalendarProviderCalendar provider interface
interface CalendarProvider {
/**
* Get all calendars available on the device.
* @returns An array of Calendar objects with their metadata.
*/
getCalendars(): Promise<Calendar[]>
/**
* Query calendar events matching the given options.
* @param options - Query filters (calendar IDs, date range, search text, limit).
* @returns An array of matching CalendarEvent objects.
*/
getEvents(options?: EventQueryOptions): Promise<CalendarEvent[]>
/**
* Get a single event by ID
* @param eventId - Event ID
* @param calendarId - Calendar ID
*/
getEventById(eventId: string, calendarId: string): Promise<CalendarEvent | null>
/**
* Create a new event
* @param event - Event data
*/
createEvent(event: EventInput): Promise<CalendarEvent>
/**
* Update an existing event
* @param eventId - Event ID
* @param event - Updated event data
*/
updateEvent(eventId: string, event: Partial<EventInput>): Promise<CalendarEvent>
/**
* Delete an event
* @param eventId - Event ID
* @param calendarId - Calendar ID
*/
deleteEvent(eventId: string, calendarId: string): Promise<void>
/**
* Open native calendar for a date
* @param date - Date to show
*/
openCalendar(date?: Date): Promise<void>
/**
* Open event in native calendar
* @param eventId - Event ID
*/
openEvent(eventId: string): Promise<void>
/**
* Get permission status
*/
getPermissionStatus(): Promise<CalendarPermissionStatus>
/**
* Request permission
*/
requestPermission(): Promise<CalendarPermissionStatus>
/**
* Open system settings for calendar permission
*/
openSettings(): Promise<void>
/**
* Get the platform's calendar capabilities.
* @returns The capabilities indicating which calendar features are supported.
*/
getCapabilities(): Promise<CalendarCapabilities>
}
EventAttendeeA calendar event attendee with email, name, RSVP status, and organizer/optional flags.
interface EventAttendee {
/** Attendee email */
email: string
/** Attendee name */
name?: string
/** Attendance status */
status?: 'pending' | 'accepted' | 'declined' | 'tentative'
/** Whether attendee is organizer */
isOrganizer?: boolean
/** Whether attendee is optional */
isOptional?: boolean
}
EventQueryOptionsEvent query options
interface EventQueryOptions {
/** Calendar IDs to query (all if not specified) */
calendarIds?: string[]
/** Start date range (ISO string) */
startDate?: string
/** End date range (ISO string) */
endDate?: string
/** Search query */
query?: string
/** Maximum results */
limit?: number
}
EventReminderEvent reminder/alarm
interface EventReminder {
/** Minutes before event to trigger reminder */
minutes: number
/** Reminder method */
method?: 'alert' | 'email' | 'sms'
}
RecurrenceRuleRecurrence rule
interface RecurrenceRule {
/** Recurrence frequency */
frequency: 'daily' | 'weekly' | 'monthly' | 'yearly'
/** Interval between occurrences */
interval?: number
/** End date (ISO string) */
endDate?: string
/** Number of occurrences */
count?: number
/** Days of week (0-6, Sunday-Saturday) */
daysOfWeek?: number[]
/** Days of month (1-31) */
daysOfMonth?: number[]
/** Months (1-12) */
months?: number[]
}
CalendarPermissionStatusPermission status
type CalendarPermissionStatus = 'granted' | 'denied' | 'limited' | 'prompt' | 'unsupported'
EventInputEvent input for creation/update
type EventInput = Omit<CalendarEvent, 'id'> & { id?: string }
createEvent(event)Create a new calendar event.
function createEvent(event: EventInput): Promise<CalendarEvent>
event — The event data to create (title, dates, attendees, etc.).Returns: The created CalendarEvent with its assigned ID.
deleteEvent(eventId, calendarId)Delete a calendar event.
function deleteEvent(eventId: string, calendarId: string): Promise<void>
eventId — The ID of the event to delete.calendarId — The calendar ID containing the event.Returns: A promise that resolves when the event is deleted.
eventsOverlap(event1, event2)Check if two calendar events overlap in time.
function eventsOverlap(event1: CalendarEvent, event2: CalendarEvent): boolean
event1 — The first event to compare.event2 — The second event to compare.Returns: Whether the two events have overlapping time ranges.
formatEventTimeRange(event, locale)Format an event's time range as a human-readable string. Handles all-day events, same-day events, and multi-day events differently.
function formatEventTimeRange(event: CalendarEvent, locale?: string): string
event — The calendar event to format.locale — The locale code for date/time formatting (default: 'en-US').Returns: A formatted time range string (e.g., "9:00 AM - 10:00 AM" or "Mon, Jan 5").
getCalendars()Get all calendars available on the device.
function getCalendars(): Promise<Calendar[]>
Returns: An array of Calendar objects with their metadata.
getCapabilities()Get the platform's calendar capabilities.
function getCapabilities(): Promise<CalendarCapabilities>
Returns: The capabilities indicating which calendar features are supported.
getEventById(eventId, calendarId)Get a single event by its ID.
function getEventById(eventId: string, calendarId: string): Promise<CalendarEvent | null>
eventId — The event ID to look up.calendarId — The calendar ID containing the event.Returns: The matching CalendarEvent, or null if not found.
getEventDuration(event)Get the duration of a calendar event in minutes.
function getEventDuration(event: CalendarEvent): number
event — The calendar event to measure.Returns: The event duration in minutes, rounded to the nearest integer.
getEvents(options)Query calendar events matching the given options.
function getEvents(options?: EventQueryOptions): Promise<CalendarEvent[]>
options — Query filters (calendar IDs, date range, search text, limit).Returns: An array of matching CalendarEvent objects.
getPermissionStatus()Get the current calendar permission status.
function getPermissionStatus(): Promise<CalendarPermissionStatus>
Returns: The permission status: 'granted', 'denied', 'limited', 'prompt', or 'unsupported'.
getProvider()Get the current device calendar provider.
function getProvider(): CalendarProvider
Returns: The active CalendarProvider instance.
hasProvider()Check if a calendar provider has been registered.
function hasProvider(): boolean
Returns: Whether a CalendarProvider has been bonded.
openCalendar(date)Open the native calendar app, optionally showing a specific date.
function openCalendar(date?: Date): Promise<void>
date — The date to navigate to (defaults to today).Returns: A promise that resolves when the calendar app is opened.
openEvent(eventId)Open a specific event in the native calendar app.
function openEvent(eventId: string): Promise<void>
eventId — The ID of the event to open.Returns: A promise that resolves when the event is opened.
openSettings()Open the system settings screen for calendar permissions.
function openSettings(): Promise<void>
Returns: A promise that resolves when the settings screen is opened.
parseQuickEvent(text, calendarId)Parse a text string into a quick calendar event. Uses basic keyword matching for time references. Returns null if no title can be extracted.
function parseQuickEvent(text: string, calendarId: string): EventInput | null
text — Natural language event text (e.g., "Meeting tomorrow at 3pm").calendarId — The calendar ID to assign the event to.Returns: An EventInput for a 1-hour event starting at the next hour, or null if parsing fails.
requestPermission()Request calendar permissions from the user.
function requestPermission(): Promise<CalendarPermissionStatus>
Returns: The resulting permission status after the request.
setProvider(provider)Set the device calendar provider.
function setProvider(provider: CalendarProvider): void
provider — CalendarProvider implementation to register.updateEvent(eventId, event)Update an existing calendar event.
function updateEvent(eventId: string, event: Partial<EventInput>): Promise<CalendarEvent>
eventId — The ID of the event to update.event — The partial event data to merge with the existing event.Returns: The updated CalendarEvent.
Peer dependencies:
@molecule/app-bond ^1.0.1@molecule/app-i18n ^1.0.1@molecule/app-bond
@molecule/app-i18n
Every accessor THROWS until setProvider() is called — there is no
web fallback and no prebuilt provider package ships with molecule;
supply a CalendarProvider from your native runtime and gate the UI on
hasProvider(). Browsers cannot read/write the OS calendar store — on
web, integrate a server-side calendar API (@molecule/api-calendar)
instead.
Do not confuse this with @molecule/app-calendar — they share nothing
but a similar name. This package bonds its provider under the distinct
'device-calendar' key (the calendar UI core uses 'calendar'), so both
can be wired in the same app without clobbering each other in the registry.
Request permission from a user gesture at the point of use; a denied
prompt is remembered — recovery is openSettings(). iOS can grant
'limited' (write-only add) access.
Respect Calendar.readOnly (subscribed/birthday calendars reject
writes) and check getCapabilities() before offering attendees or
recurrence editing — support differs per platform.