API Docs

Module for creating and displaying macOS system notifications.

macOS notifications require user permission before they will appear. Request it once (typically at startup) via hs.permissions.requestNotifications() and it will be remembered across sessions:

hs.permissions.requestNotifications().then(granted => {
    if (granted) hs.notify.show("Hammerspoon", "Notifications are enabled!")
})

Quick notification

// Fire and forget
hs.notify.show("Build complete", "Your project compiled successfully.")

// With a callback invoked when the user interacts
hs.notify.show("Build complete", "Click to view the log.", (response) => {
    console.log("User tapped:", response.actionIdentifier)
})

Rich notification

const n = hs.notify.create({
    title:    "New message",
    subtitle: "From Alice",
    body:     "Are you free tonight?",
    sound:    true,
    threadIdentifier: "messages-alice",
    actions: [
        { identifier: "REPLY", title: "Reply", textInput: true,
          textInputButtonTitle: "Send", textInputPlaceholder: "Type a reply…" },
        { identifier: "DISMISS", title: "Dismiss", destructive: true }
    ],
    callback: (response) => {
        if (response.actionIdentifier === "REPLY") {
            console.log("Reply text:", response.userText)
        }
    }
})
n.send()
// Later, if needed:
n.withdraw()

Callback response object

The callback function receives a single object with these properties:

Property Type Description
actionIdentifier string "DEFAULT" when the user tapped the notification body; "DISMISS" when dismissed (if .customDismissAction is set); otherwise the action's identifier string
userText string? Text entered in a textInput action; only present when applicable
userInfo object The userInfo object originally passed to create(), if any
notificationId string The notification's unique identifier

Options for create()

Key Type Default Description
title string (required) The bold heading line
subtitle string A second line shown beneath the title
body string The main message body
sound boolean | string true true = default sound, false = no sound, string = named .aiff file
badge number Value to show on the app icon badge
threadIdentifier string Groups related notifications visually in Notification Center
userInfo object {} Arbitrary payload passed back to the callback
interruptionLevel string "active" "passive", "active", or "timeSensitive" — controls Focus/DND behaviour (macOS 12+)
trigger object When to deliver the notification (see below). Omit for immediate delivery.
actions array Action buttons (see below)
callback function Invoked when the user interacts with the notification

Triggers

Pass a trigger object in create()'s options to schedule the notification instead of delivering it Time interval — deliver after a fixed delay in seconds (minimum 60 s):

trigger: { type: "timeInterval", interval: 300 }

Calendar — deliver at a specific date/time. Provide either a JS Date object or individual date-component keys; any omitted component matches every value:

// At a specific moment
trigger: { type: "calendar", date: new Date("2026-06-01T09:00:00") }

// At 09:00 on the next day that matches (e.g. next Monday, weekday 2)
trigger: { type: "calendar", weekday: 2, hour: 9, minute: 0 }

Supported component keys: year, month, day, hour, minute, second, weekday.

Action objects

Key Type Default Description
identifier string (required) Unique identifier passed to the callback
title string (required) Button label
destructive boolean false Renders the title in a destructive (red) style
foreground boolean false Brings Hammerspoon to the foreground when tapped
textInput boolean false Converts this action to an inline text-reply button
textInputButtonTitle string "Send" Label on the reply send button (requires textInput: true)
textInputPlaceholder string "" Placeholder shown in the text field (requires textInput: true)

Types

This module provides the following types:

Properties

This module has no properties.

Methods

hs.notify.show(title, body, callback) -> None

Display a notification immediately. Receives a response object (see module docs for shape).
hs.notify.show(title, body, callback) -> None
Name Type Description
title string The notification title
body string The notification body text
callback JSValue Optional function called when the user taps the notification.
None
hs.notify.show("Build complete", "Your project compiled successfully.")

hs.notify.create(options) -> HSNotification

Create a richly configured notification without sending it yet.
hs.notify.create(options) -> HSNotification
Name Type Description
options JSValue A JavaScript object — see module documentation for supported keys.
HSNotification
An `HSNotification` object. Call `.send()` on it to deliver the notification.
const n = hs.notify.create({ title: "Hello", body: "World" })
n.send()

hs.notify.removeAllDelivered() -> None

Remove all delivered Hammerspoon notifications from Notification Center.
hs.notify.removeAllDelivered() -> None
None
hs.notify.removeAllDelivered()

hs.notify.removeAllPending() -> None

Cancel all pending (not yet delivered) Hammerspoon notifications.
hs.notify.removeAllPending() -> None
None
hs.notify.removeAllPending()