opentui

Build terminal UIs with OpenTUI. Covers Core, frameworks, components, application APIs, testing, extensions, integrations, deployment, and public API lookup.

Install
npx skills add 'https://github.com/anomalyco/opentui/tree/main/packages/web/src/content'
Download bundle ↓
main · ac753b4Scanned 2026-09-15

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗

docs/core-concepts/notifications.mdx

docs/core-concepts/notifications.mdxBrowse 89 files
View on GitHub
← Back to SKILL.md

title: Notifications description: Trigger terminal-mediated desktop notifications skill: intents: [notifications, terminal, osc, renderer]

Notifications

OpenTUI asks the terminal emulator to show a desktop notification with an operating system command (OSC) sequence. It does not call host notification tools.

const ok = renderer.triggerNotification("Build finished", "OpenTUI")

renderer.triggerNotification(message, title?) returns true when OpenTUI selects a protocol and queues its output. It does not confirm that the terminal or desktop displayed a notification.

The method returns false in these cases:

  • The renderer is destroyed.
  • OpenTUI has not selected a notification protocol.
  • Notification detection or an override disabled the capability.
  • Local encoding, allocation, or output generation fails.

Detection timing

Check detection state through renderer capabilities:

if (renderer.capabilities?.notifications) {
  renderer.triggerNotification("Tests passed", "CI")
}

renderer.on("capabilities", (capabilities) => {
  console.log("notification capability", capabilities.notifications)
})

createCliRenderer() starts terminal queries, but it does not wait for all replies before it resolves. The renderer updates capabilities and emits the capabilities event as replies arrive. The startup capability handler stops after 5 seconds.

A false value can mean that no protocol is supported. It can also mean that asynchronous detection has not selected one yet. Remote and multiplexer sessions often start in this state. Read Terminal capabilities for the complete detection lifecycle.

OpenTUI uses these sources, from strongest to weakest:

  1. OPENTUI_NOTIFICATION_PROTOCOL overrides.
  2. OSC 99 and iTerm2 capability-query replies.
  3. XTVERSION terminal identity.
  4. Terminal environment heuristics.

An OSC 99 reply must include the OpenTUI query identifier, p=?, and title support. An iTerm2 capability reply selects OSC 9 only when its feature codes contain No.

Known terminal identities select these protocols:

ProtocolDetected terminal families
OSC 99Kitty and foot
OSC 777Ghostty, WezTerm, Warp, hterm, Blink, Contour, VTE, GNOME Terminal, Tilix, Terminator, Xfce, rxvt, and Windows Terminal
OSC 9iTerm, Apple Terminal, Terminal.app, and ConEmu

Environment hints can select the same protocols. TERM_FEATURES with No selects OSC 9. WT_SESSION selects OSC 777. Detection is terminal-mediated and does not call notify-send, AppleScript, PowerShell, or another platform notification command.

Protocol output

ProtocolOutput behavior
OSC 99Sends base64 title and body payloads with one generated notification ID
OSC 777Sends notify, title, and body fields. Control bytes and semicolons become spaces
OSC 9Combines a nonempty title and body as title: message. Control bytes become spaces

When no title is supplied, each protocol sends the message in its supported body form.

Terminal behavior

Terminal and operating system settings decide how a notification appears. A terminal can ignore a valid sequence. Some terminals show a banner only while unfocused. Desktop settings can also store a notification without showing a banner.

Multiplexers

tmux does not forward raw notification OSC sequences. When OpenTUI detects renderer.capabilities?.multiplexer === "tmux", it wraps the selected protocol in tmux device control string (DCS) passthrough. tmux must allow passthrough:

set -g allow-passthrough on

Use allow-passthrough all if notifications need to work from panes that are not visible.

Zellij notification forwarding uses OSC 99. OpenTUI ignores inherited outer-terminal heuristics inside Zellij. It enables notifications only after a matching OSC 99 query reply or an explicit protocol override. Selected OSC 99 output remains raw instead of using tmux wrapping.

For a local GNU Screen session with STY set, OpenTUI wraps a selected protocol in Screen DCS passthrough. Screen does not itself select a notification protocol, so detection or an override must still enable one.

In an SSH session, the renderer sends the sequence to the client terminal. The server desktop is not the notification destination.

Overrides

Use an override when detection cannot identify the final terminal path:

OPENTUI_NOTIFICATION_PROTOCOL=osc99
OPENTUI_NOTIFICATIONS=0

OPENTUI_NOTIFICATION_PROTOCOL accepts these protocol values:

ValueResult
osc9, osc777, osc99Force that protocol
none, 0, false, offDisable notification protocols
1, true, onKeep automatic selection

The string comparisons for protocol names and words are case-insensitive. OPENTUI_NOTIFICATIONS=0, false, or off also disables notifications. Other values do not force support. An explicit disable remains authoritative when later query replies arrive.

See Environment variables for configuration timing. Protocol overrides assert support and can still produce no desktop notification when a terminal or multiplexer does not accept that protocol.

Example

See the notification demo for detection state, protocol output, and interactive notification requests.

Next