🕒 Current local time
Refreshes every second. Alarms are checked against this same clock.
➕ New alarm
🔔 Audio cue
Some browsers require a click on the page before they will let audio play. Clicking Add alarm counts.
Use the Dismiss button next to the ringing alarm to silence it.
📋 Scheduled alarms
No alarms scheduled. Fill out the form on the left and press Add alarm.
-
{{ String(a.hour).padStart(2, '0') }}:{{ String(a.minute).padStart(2, '0') }}{{ a.label || '(no label)' }}{{ a.repeatDaily ? 'Repeats daily' : 'One-shot' }} · {{ a.enabled ? (a.ringing ? 'RINGING' : 'armed') : 'disabled' }}
ℹ️ About Alarm Clock
What this tool does
The Alarm Clock lets you schedule one or more alarms at a future wall-clock time (hour and minute, in your local timezone). When an alarm reaches its trigger time, the page plays a short audio cue and shows a ringing banner until you dismiss it. Each alarm can optionally repeat daily — after a daily alarm fires and you dismiss it, it re-arms itself for the same time on the next calendar day.
How it works (technical details)
- Pure client-side. Every alarm definition, the ringing state, and the audio cue all live in your browser. No request is sent to any server — there is no API endpoint for this tool.
-
localStorage persistence. Alarms are saved
under the key
oct.alarm-clock.v1so they survive page reloads and Turbo Drive navigations. If localStorage is unavailable (private browsing, blocked by site settings) the tool falls back silently to in-memory state and your alarms will simply not persist across reloads. -
Polling loop. A 1-second
setIntervalcomparesDate.now()with each enabled alarm's next-fires-at timestamp. When an alarm's time arrives, it flips to ringing and (if enabled) the audio cue plays. - Audio cue. A 880 Hz sine tone plays for half a second using the Web Audio API. Most browsers require a user interaction (such as clicking Add alarm) before they will let a page play sound — that click counts as the gesture.
-
Background-tab limits. Browsers throttle
setIntervalin background tabs (typically to one tick per second, sometimes less if the tab is fully hidden for a long time). The wall-clock comparison still uses freshDate.now()on the next visible tick, so a missed alarm fires as soon as the tab is foregrounded — but a tab that has been hidden for a long time may ring late. For time-critical wake-ups, also use a phone alarm.
Use cases
- Pomodoro-style work sessions with a repeating end-of-block alarm.
- Daily stand-up reminders using the daily-repeat option.
- Personal reminders — "tea is steeping", "laundry timer", "meeting in 15 minutes".
- Deadline alerts that need an audible cue but should not interrupt other apps.
Privacy note
All alarm definitions and the ringing state are stored locally in
localStorage. No network request is made. Nothing
about your alarms — labels, times, or fire history — is sent to
any server, ours or otherwise.
References
- MDN — window.setInterval — the timing primitive driving the once-per-second wall-clock check.
- MDN — Window.localStorage — origin-scoped persistent key/value store used to remember alarms across reloads.
- MDN — Web Audio API — the API used to synthesize the alarm beep.
- MDN — <input type="time"> — the HH:MM picker for scheduling alarms in local time.
- For a one-shot future deadline rather than a recurring wall-clock alarm, see the Countdown Timer.