30817:quick-reactions

Quick Reactions

review

chad

published
2026-10-09

draft optional

This NIP defines kind 10077, a replaceable list of the reactions a user wants offered first, in the order they chose: the row of one-tap emoji shown next to a "react" button.

Event

{
  "kind": 10077,
  "content": "",
  "tags": [
    ["reaction", "🔥"],
    ["reaction", "🙏"],
    ["reaction", ":soapbox:", "https://gleasonator.com/emoji/Gleasonator/soapbox.png", "30030:79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6:gleasonator"],
    ["reaction", "+"]
  ]
}

Each reaction tag is:

["reaction", <content>, <image-url>, <emoji-set-address>]
  • <content> is exactly what a NIP-25 reaction would put in its .content: an emoji, +, -, or a :shortcode:.
  • <image-url> is required when <content> is a :shortcode: custom emoji (NIP-30) and absent otherwise.
  • <emoji-set-address> is optional: the 30030:<pubkey>:<d> emoji set the custom emoji came from.

.content is empty.

Order

Tag order is the order the user chose. Clients MUST preserve it, and MUST NOT append new entries at the end by default as NIP-51 suggests for other lists; an entry goes where the user put it.

A client that shows fewer slots than the list holds SHOULD show the first entries, so every row a user sees is a prefix of the same list.

When the list has fewer entries than a client has slots, the client MAY fill the rest however it likes (most-used reactions, defaults). Those filled-in entries are not part of the list and MUST NOT be published unless the user chooses them.

Reacting

Reacting with an entry publishes a kind 7 whose .content is the entry's <content>. For a custom emoji the reaction also carries the NIP-30 tag built from the entry:

["emoji", <shortcode>, <image-url>, <emoji-set-address>]

where <shortcode> is <content> without its colons. The custom emoji does not need to be in the user's kind 10030 emoji list or any pack they hold; the entry carries everything needed to send it.

Editing

Every change replaces the whole list, so clients:

  • MUST publish only on an explicit user action (picking, removing or reordering an entry), never on load or to save defaults.
  • SHOULD read the latest version from the user's write relays immediately before publishing and build on it, and SHOULD NOT publish when that read fails.
  • MUST keep entries they cannot display (for example a custom emoji while custom emoji are turned off) and tags they do not recognize.
  • SHOULD drop duplicate <content> values, keeping the first.

Discussion

Connect a key to comment.