Skip to content

Text, emoji, and other languages

Wire status: Mesh chat and short status strings SHOULD use payloadType = 0x01 (TEXT_UTF8) — see Payloads. Longer text sent as chunked UTF-8 MAY use PAYLOAD_BODY_V2 with fileType = 0x01 (Text) so each frame carries currentIndex / totalCount.

UTF-8 everywhere

UTF-8 (without BOM) is the encoding for TEXT_UTF8 bodies and for chunkBytes when payloadType = 0x04 and fileType = 0x01 (Text). This includes:

  • Emoji (multi-codepoint sequences, skin tones, ZWJ sequences).
  • CJK ideographs, Arabic shaping contexts, combining marks.

Display requirements

Conforming UI implementations MUST:

  • Decode UTF-8 with full Unicode scalar value support (not UCS-2).
  • Handle grapheme clusters for cursor movement (optional but recommended).

Example bytes

String: Hello 🔥 你好

Hex (UTF-8):

48 65 6C 6C 6F 20 F0 9F 94 A5 20 E4 BD A0 E5 A5 BD
  • F0 9F 94 A5 = 🔥 (U+1F525, 4-byte UTF-8)
  • E4 BD A0 = 你
  • E5 A5 BD = 好

Length limits

Full discussion (PHY vs header field vs fragmentation): Maximum payload lengths.

ContextRecommended maxNotes
Single-frame TEXT_UTF8 (0x01)≤ ~230 bytes UTF-8 (encrypted, minimal base, no extra blocks)Upper bound 255 − prefixBytes − micLen − 1 (utf8Len prefix) — see Payload limits
PAYLOAD_BODY_V2 Text chunk (0x04, fileType=0x01)product-defined per PHYSubtract 8-byte PAYLOAD_BODY_V2 prefix + chunkLen (1) from cipherLen budget
Default community (channelHash == 0x0000)same PHY arithmeticAES-CCM-4 inner tail (MIC); UTF-8 after decrypt
Fragmented chat64 KiB – 1 MiBVia Fragmentation

Interop with notifications

Notification previews take the first grapheme-aware line up to N characters, with emoji-safe truncation.

Mixed payloads

Chat apps MAY embed structured cards using CBOR or MessagePack inside a TEXT_RICH future type (0x0203 reserved). Core spec stays UTF-8 text-first.

LowMeshOS — always open-source mesh protocol documentation