Skip to main content

Introduction

LibXMTP provides a comprehensive messaging system built on MLS (Messaging Layer Security) that supports various content types, message enrichment, and real-time streaming. Messages are the core unit of communication in XMTP groups and conversations.

Core message types

LibXMTP distinguishes between several message representations:

StoredGroupMessage

Raw message data as stored in the local database. Contains encrypted message bytes, metadata, and delivery status. Key fields:
  • id - Unique message identifier (bytes)
  • group_id - Group this message belongs to (bytes)
  • decrypted_message_bytes - Encrypted content payload
  • sent_at_ns - Timestamp in nanoseconds
  • sender_inbox_id - Inbox ID of sender
  • sender_installation_id - Installation ID of sender
  • kind - Message kind (application, membership change, etc.)
  • delivery_status - Published, unpublished, or failed
  • content_type - Type of content (text, reaction, etc.)

DecodedMessage

Enriched message with decoded content, reactions, and reply metadata. This is the primary type used when displaying messages to users. Structure:
See DecodedMessage for detailed documentation.

Message (Node.js bindings)

Simplified message representation exposed to Node.js applications:

Message lifecycle

Sending messages

  1. Encode content - Convert your data to EncodedContent using a codec
  2. Send - Call conversation.send() with encoded content and options
  3. Publish - Message is encrypted, signed, and sent to the network
  4. Store - Message is saved to local database
Send options:
  • shouldPush - Whether to trigger push notifications
  • optimistic - If true, returns immediately without waiting for network confirmation

Receiving messages

Messages can be retrieved in two ways: Query historical messages:
Stream real-time messages:

Message enrichment

The list_enriched_messages() / listEnrichedMessages() methods return DecodedMessage instances with additional context:
  • Reactions - All reactions to this message
  • Reply count - Number of replies referencing this message
  • Reply context - For reply messages, includes the referenced message
  • Deletion state - Marks messages deleted by sender or admin
Example:

Message filtering

Filter messages by various criteria:
Available filters:
  • sentAfterNs / sentBeforeNs - Time range in nanoseconds
  • limit - Maximum number of messages
  • direction - 'ascending' or 'descending'
  • contentTypes - Filter by content type
  • deliveryStatus - Filter by delivery status

Optimistic sending

For faster UI updates, use optimistic sending:
Or prepare messages for batch publishing:

Message deletion

Messages can be deleted by the sender or by group admins:
Deleted messages are replaced with a placeholder in enriched message lists:
The original message data remains in the database but is marked as deleted and won’t display content to users.

Message kinds

Messages have different purposes indicated by their kind:
Application messages include:
  • Text, reactions, replies
  • Attachments, read receipts
  • Custom content types
Membership change messages track:
  • Members added/removed
  • Admin role changes
  • Group metadata updates

Delivery status

Track message delivery state:
Check status:

Best practices

Performance

  • Use listMessages() for basic message lists (faster)
  • Use listEnrichedMessages() only when you need reactions/replies
  • Implement pagination with limit and time-based filtering
  • Stream messages for real-time updates instead of polling

Error handling

Content type detection

Always check content type before accessing type-specific fields:

See also