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

expo-alarm-kit

v0.1.6

Published

An Expo module for iOS AlarmKit integration - schedule native alarms with optional app launch on dismissal

Downloads

472

Readme

expo-alarm-kit

An Expo module for iOS AlarmKit integration. Schedule native iOS alarms with optional app launch on dismissal or snooze intents.

⚠️ Requirements:

  • iOS Deployment Target: 26.0+
  • Expo SDK: 50+
  • Framework: Apple AlarmKit

Features

  • 📅 Schedule Native Alarms: Create alarms that persist even if the app is killed.
  • 🔄 Repeating Alarms: Support for weekly repeating schedules.
  • 🚀 App Launch Triggers: Optionally launch your app when the user dismisses or snoozes the alarm.
  • 🧩 Custom Intent Payloads: Attach optional payload strings for dismiss/snooze events.
  • 🎨 Customization: Configure titles, snooze settings, and tint colors.
  • 💾 Shared State: Uses App Groups to synchronize alarm state between the system and your app.

Installation

npm install expo-alarm-kit
# or
yarn add expo-alarm-kit

Since this module utilizes native iOS frameworks, you must prebuild your project:

npx expo prebuild

Configuration (Required)

This module requires native iOS configuration to function. If these steps are skipped, the module will throw errors.

1. Set Deployment Target

In Xcode, navigate to your project's Build Settings and ensure the iOS Deployment Target is set to 26.0 or higher.

Error: Failing to do this will result in a "Module not found: ExpoAlarmKit" error.

2. Add Usage Description

Apple requires you to justify why you need access to alarms.

  1. Open your project in Xcode.
  2. Select your app target and go to the Info tab.
  3. Add a new key: Privacy - Alarm Kit Usage Description.
  4. Value: Enter a short description (e.g., "We use alarms to wake you up at your scheduled times.")

3. Configure App Groups

App Groups allow the Alarm extension to communicate with your main application.

  1. In Xcode, select your app target.
  2. Go to Signing & Capabilities.
  3. Click + Capability and select App Groups.
  4. Add a new group identifier (e.g., group.com.yourcompany.yourapp).

Important: This identifier must match exactly what you pass to the configure() method in your JavaScript code.


Usage

1. Initialization

You must configure the module with your App Group ID as early as possible in your app's lifecycle (e.g., inside App.tsx or _layout.tsx).

import { useEffect } from 'react';
import { configure, getLaunchPayload } from 'expo-alarm-kit';

export default function App() {
  useEffect(() => {
    // 1. Initialize the module
    const isConfigured = configure('group.com.yourcompany.yourapp');
    
    if (!isConfigured) {
      console.error('Failed to configure ExpoAlarmKit. Check App Group ID.');
    }

    // 2. Check if app was launched via an alarm dismiss/snooze intent
    const payload = getLaunchPayload();
    if (payload) {
      console.log('App launched by alarm:', payload.alarmId);
      // Navigate to specific screen or perform action
    }
  }, []);

  return <YourAppContent />;
}

2. Scheduling Alarms

import { 
  scheduleAlarm, 
  scheduleRepeatingAlarm, 
  generateUUID, 
  requestAuthorization 
} from 'expo-alarm-kit';

const handleSchedule = async () => {
  // Always request permission first
  const authStatus = await requestAuthorization();
  if (authStatus !== 'authorized') return;

  // Example: Schedule a one-time alarm for 1 hour from now
  const alarmId = generateUUID();
  
  await scheduleAlarm({
    id: alarmId,
    epochSeconds: Date.now() / 1000 + 3600, 
    title: 'Power Nap Over',
    soundName: 'alarm.wav', // Must be in Xcode bundle resources
    launchAppOnDismiss: true,
    dismissPayload: 'nap-dismiss',
    doSnoozeIntent: true,
    launchAppOnSnooze: true,
    snoozePayload: 'nap-snooze',
    snoozeDuration: 300, // 5 minutes
  });
};

const handleRepeatingSchedule = async () => {
  // Example: Schedule for Mon-Fri at 7:30 AM
  const id = generateUUID();
  
  await scheduleRepeatingAlarm({
    id,
    hour: 7,
    minute: 30,
    weekdays: [2, 3, 4, 5, 6], // 1=Sun, 2=Mon...
    title: 'Work Alarm',
    launchAppOnDismiss: true,
    dismissPayload: 'work-dismiss',
    doSnoozeIntent: true,
    launchAppOnSnooze: false,
    snoozePayload: 'work-snooze',
  });
};

3. Managing Alarms

import { cancelAlarm, getAllAlarms } from 'expo-alarm-kit';

// Get list of active alarm IDs
const activeAlarms = getAllAlarms();

// Cancel a specific alarm
await cancelAlarm('your-alarm-uuid');

How It Works

App Groups & Shared Storage

This module relies on iOS App Groups to share UserDefaults between the main app process and the system alarm extension.

  • Persistence: When you schedule an alarm, the metadata is written to this shared storage.
  • Sync: Both the Native Module and the App Extension read from this same source of truth.

App Launch on Dismiss/Snooze

When launchAppOnDismiss: true or (doSnoozeIntent: true + launchAppOnSnooze: true) is set:

  1. The user dismisses or snoozes the alarm on the lock screen.
  2. The system launches your app in the background/foreground.
  3. The module writes a LaunchPayload to the shared storage.
  4. When your React Native JS bundle loads, calling getLaunchPayload() retrieves and clears this data, allowing you to react to the event.

API Reference

Configuration & Auth

configure(appGroupIdentifier: string): boolean

Initializes the module. Must be called before other methods.

  • Returns: true if the App Group was accessible.

requestAuthorization(): Promise<AuthorizationStatus>

Prompts the user for permission to schedule alarms.

  • Returns: 'authorized' | 'denied' | 'notDetermined'

Scheduling

scheduleAlarm(options): Promise<boolean>

Schedules a non-repeating alarm.

Options Object:

| Property | Type | Required | Description | | --- | --- | --- | --- | | id | string | Yes | Unique UUID. | | epochSeconds | number | No* | Unix timestamp (seconds) for the alarm. | | date | Date | No* | Alternative: JS Date object. | | title | string | Yes | Main text displayed on lock screen. | | soundName | string | No | Filename of sound in app bundle. | | launchAppOnDismiss | boolean | No | If true, opens app when stopped. | | dismissPayload | string | No | Optional payload string for dismiss intent (null in payload if omitted). | | doSnoozeIntent | boolean | No | If true, enables custom snooze intent (default: false). | | launchAppOnSnooze | boolean | No | If true, opens app when snooze intent runs. | | snoozePayload | string | No | Optional payload string for snooze intent (null in payload if omitted). | | stopButtonLabel | string | No | Text for stop button (default: 'Stop'). | | snoozeButtonLabel | string | No | Text for snooze button. | | stopButtonColor | string | No | Hex color string. | | snoozeButtonColor | string | No | Hex color string. | | tintColor | string | No | Overall UI tint color. | | snoozeDuration | number | No | Duration in seconds (default: 540). |

*Note: Provide either epochSeconds OR date, not both.

scheduleRepeatingAlarm(options): Promise<boolean>

Schedules a weekly repeating alarm.

Options Object:

| Property | Type | Required | Description | | --- | --- | --- | --- | | id | string | Yes | Unique UUID. | | hour | number | Yes | 0-23 | | minute | number | Yes | 0-59 | | weekdays | number[] | Yes | Array of integers: 1 (Sun) to 7 (Sat). | | title | string | Yes | Main text displayed. | | launchAppOnDismiss | boolean | No | If true, opens app when stopped. | | dismissPayload | string | No | Optional payload string for dismiss intent (null in payload if omitted). | | doSnoozeIntent | boolean | No | If true, enables custom snooze intent (default: false). | | launchAppOnSnooze | boolean | No | If true, opens app when snooze intent runs. | | snoozePayload | string | No | Optional payload string for snooze intent (null in payload if omitted). | | ... | ... | ... | Supports all visual options from scheduleAlarm. |


Utilities

cancelAlarm(id: string): Promise<boolean>

Cancels the alarm in AlarmKit and removes it from shared storage.

generateUUID(): string

Helper to generate a unique ID string for new alarms.

getAllAlarms(): string[]

Returns an array of IDs for all currently scheduled alarms.

getLaunchPayload(): LaunchPayload | null

Returns data if the app was launched via an alarm.

interface LaunchPayload {
  alarmId: string;
  payload: string | null;
}

removeAlarm(id: string): void

Advanced: Removes an alarm from local storage records without cancelling the native AlarmKit instance. Use cancelAlarm for standard usage.


Known Issues

  • Custom Labels/Colors: The stopButtonLabel, stopButtonColor properties are not correctly modifying the stop button/slider.