react-native-alarm-scheduler

Quick start

Schedule your first alarm, then handle it when it fires.

Ask for permission

Alarm scheduling is gated on both platforms. Always check before scheduling.

import AlarmScheduler from 'react-native-alarm-scheduler';

const permissions = await AlarmScheduler.requestPermissionsAsync();

if (!permissions.canScheduleExactAlarms) {
  // Send the user to settings and explain why the alarm needs this.
  await AlarmScheduler.openAlarmSettingsAsync();
}

On Android 12+ this opens the exact alarm settings screen when exact alarms are not allowed. On iOS 26+ it requests AlarmKit authorization.

Schedule an alarm

const alarm = await AlarmScheduler.scheduleAlarmAsync({
  hour: 7,
  minute: 30,
  title: 'Morning alarm',
  weekdays: [1, 2, 3, 4, 5],
});

console.log(alarm.id, alarm.timestamp);

hour is 24-hour time (0–23), minute is 0–59, and weekdays uses ISO numbering where 1 is Monday and 7 is Sunday. Omit weekdays for a one-shot alarm; omit timestamp and the module schedules the next matching time.

Handle the alarm when it fires

Events only arrive when a JS runtime happens to be alive. The reliable pattern is to reconcile from the native records on every launch and foreground:

const handoff = await AlarmScheduler.getPendingNativeAlarmHandoffAsync();
const context = handoff ? null : await AlarmScheduler.getCurrentAlarmContextAsync();
const alarmId = handoff?.alarmId ?? context?.id;

if (alarmId) {
  router.replace(`/alarm/${alarmId}`);
  await AlarmScheduler.clearPendingNativeAlarmHandoffAsync();
}

List and cancel

const alarms = await AlarmScheduler.getScheduledAlarmsAsync();

for (const alarm of alarms) {
  await AlarmScheduler.cancelAlarmAsync(alarm.id);
}

Next

That is a normal alarm — the user can stop it. To keep one ringing until your app confirms the user finished something, see Completion gating.