npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@appkit/apple-calendar

v0.1.3

Published

Native macOS Calendar integration using EventKit with participation status support

Downloads

319

Readme

apple-calendar

Native macOS Calendar integration using EventKit with participation status support.

Features

  • Native EventKit Integration - Direct access to macOS Calendar via Swift
  • Participation Status - Filter events by accepted/declined/tentative/pending
  • TypeScript API - Clean, type-safe interface for Node.js
  • Pre-compiled Binary - No Swift toolchain required for end users
  • Zero Dependencies - Minimal runtime footprint
  • Fast - Native performance, no parsing overhead

Installation

npm install @appkit/apple-calendar

Requirements:

  • macOS 10.14 or later
  • Node.js 18 or later

Quick Start

import { getEventsToday, ParticipationStatus } from "@appkit/apple-calendar";

// Get today's accepted events
const events = await getEventsToday({
  participationStatus: [ParticipationStatus.Accepted],
});

console.log(events);

API Reference

Event Queries

getEventsToday(options?)

Get events for today (00:00 - 23:59).

const events = await getEventsToday({
  calendars: ["Work", "Personal"],
  includeAllDay: false,
  participationStatus: [ParticipationStatus.Accepted],
});

Options:

  • calendars?: string[] - Filter by calendar names
  • includeAllDay?: boolean - Include all-day events (default: false)
  • participationStatus?: ParticipationStatus[] - Filter by status

getEventsFromToday(days, options?)

Get events from today through N days ahead.

// Get next 7 days of accepted events
const events = await getEventsFromToday(7, {
  participationStatus: [ParticipationStatus.Accepted],
});

getUpcomingEvents(hours?, options?)

Get upcoming events starting from now.

// Get events in the next 24 hours
const events = await getUpcomingEvents(24);

getEventsBetween(startDate, endDate, options?)

Get events in a specific date range.

const start = new Date("2024-01-01");
const end = new Date("2024-01-31");
const events = await getEventsBetween(start, end);

queryEvents(options)

Low-level query with full control.

const result = await queryEvents({
  startDate: new Date(),
  endDate: new Date(Date.now() + 86400000),
  calendars: ["Work"],
  includeAllDay: true,
  participationStatus: [
    ParticipationStatus.Accepted,
    ParticipationStatus.Tentative,
  ],
});

console.log(result.events);
console.log(result.errors); // Any errors that occurred

Calendar Queries

listCalendars()

Get all available calendars.

const calendars = await listCalendars();

calendars.forEach((cal) => {
  console.log(`${cal.title} (${cal.type}) - ${cal.color}`);
});

Types

ParticipationStatus

Enum for event participation status:

enum ParticipationStatus {
  Unknown = 0, // Status not set
  Pending = 1, // Invitation pending
  Accepted = 2, // User accepted
  Declined = 3, // User declined
  Tentative = 4, // User marked as maybe
}

CalendarEvent

Event object returned by queries:

interface CalendarEvent {
  id: string;
  title: string;
  startDate: Date;
  endDate: Date;
  calendar: string;
  location?: string;
  isAllDay: boolean;
  participationStatus: ParticipationStatus;
  notes?: string;
  url?: string;
  isRecurring: boolean;
}

Calendar

Calendar object returned by listCalendars():

interface Calendar {
  title: string;
  type: string;
  isWritable: boolean;
  color?: string;
}

Examples

Filter Out Declined/Tentative Events

import {
  getEventsFromToday,
  ParticipationStatus,
} from "@appkit/apple-calendar";

// Only get events I've accepted
const acceptedEvents = await getEventsFromToday(7, {
  participationStatus: [ParticipationStatus.Accepted],
});

Query Specific Calendars

import { getEventsToday } from "@appkit/apple-calendar";

// Only work events
const workEvents = await getEventsToday({
  calendars: ["Work Calendar"],
});

// Multiple calendars
const events = await getEventsToday({
  calendars: ["Work", "Personal", "Family"],
});

Get All Events Including All-Day

import { getEventsToday } from "@appkit/apple-calendar";

const allEvents = await getEventsToday({
  includeAllDay: true,
});

List Available Calendars

import { listCalendars } from "@appkit/apple-calendar";

const calendars = await listCalendars();
console.log("Available calendars:");
calendars.forEach((cal) => {
  console.log(`- ${cal.title} (${cal.type})`);
});

Custom Date Range with Filtering

import { queryEvents, ParticipationStatus } from "@appkit/apple-calendar";

const result = await queryEvents({
  startDate: new Date("2024-01-01"),
  endDate: new Date("2024-12-31"),
  calendars: ["Work"],
  includeAllDay: false,
  participationStatus: [ParticipationStatus.Accepted],
});

console.log(`Found ${result.events.length} events`);
if (result.errors && result.errors.length > 0) {
  console.error("Errors:", result.errors);
}

Command-Line Usage

The native binary can also be used directly:

# List calendars
./dist/bin/calendar-helper calendars

# Get today's events
./dist/bin/calendar-helper events today

# Get next 7 days
./dist/bin/calendar-helper events today+7

# Get events with filters
./dist/bin/calendar-helper events \
  --days 7 \
  --calendars "Work,Personal" \
  --participation 2 \
  --include-all-day

# Custom date range
./dist/bin/calendar-helper events \
  --start 2024-01-01T00:00:00Z \
  --end 2024-01-31T23:59:59Z

Building from Source

# Install dependencies
npm install

# Build native binary and TypeScript
npm run build

# Or build separately
npm run build:native  # Build Swift binary
npm run build:ts      # Build TypeScript

Build Requirements:

  • Xcode Command Line Tools
  • Swift 5.0 or later

How It Works

This package includes a pre-compiled Swift binary that uses Apple's EventKit framework to query calendar data. The TypeScript wrapper provides a clean API that executes the binary and parses its JSON output.

Architecture:

  1. TypeScript API receives query
  2. Constructs command-line arguments
  3. Executes Swift binary (EventKit)
  4. Parses JSON response
  5. Returns typed results

Why Native?

  • icalBuddy doesn't support participation status
  • AppleScript Calendar integration is limited
  • EventKit is the official, most capable API

Privacy & Permissions

This package requires Calendar access. On first use:

  1. macOS will prompt for Calendar access
  2. Grant access to your terminal or app
  3. Future calls will work without prompts

Privacy: All queries are local-only. No data leaves your machine.

License

MIT

Contributing

Contributions welcome! Please open an issue or PR.

Troubleshooting

Binary not found:

npm run build:native

Permission denied:

  • System Settings → Privacy & Security → Calendars
  • Enable access for Terminal or your app

No events returned:

  • Check calendar names with listCalendars()
  • Verify date ranges are correct
  • Check participation status filters

Build errors:

  • Ensure Xcode Command Line Tools are installed: xcode-select --install
  • Verify Swift version: swift --version (needs 5.0+)