hs.notify
ModuleModule 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
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. |
hs.notify.show("Build complete", "Your project compiled successfully.")
hs.notify.create(options) -> HSNotification
hs.notify.create(options) -> HSNotification
| Name | Type | Description |
|---|---|---|
| options | JSValue | A JavaScript object — see module documentation for supported keys. |
const n = hs.notify.create({ title: "Hello", body: "World" })
n.send()
hs.notify.removeAllDelivered() -> None
hs.notify.removeAllDelivered() -> None
hs.notify.removeAllDelivered()
hs.notify.removeAllPending() -> None
hs.notify.removeAllPending() -> None
hs.notify.removeAllPending()