Skip to main content
This guide will walk you through the essential steps to integrate LibXMTP into your application and send your first encrypted message.

Prerequisites

Before you begin, make sure you have:
  • A supported development environment (Node.js 22+, iOS/macOS, Android, or modern browser)
  • An Ethereum wallet address for identity authentication
  • Basic familiarity with async/await patterns

Quick start steps

1

Install the library

Choose your platform and install LibXMTP using your package manager.
npm install @xmtp/node-bindings
2

Create a client

Initialize an XMTP client with your wallet credentials.
import { Client } from '@xmtp/node-bindings'

// Create a client with wallet authentication
const client = await Client.create(
  accountAddress,
  {
    env: 'production',
    dbPath: './xmtp.db'
  }
)

console.log('Client created with Inbox ID:', client.inboxId())
The client manages your local database, identity state, and network connections. Each client is bound to a single Inbox ID and Installation ID.
On first run, the client will register your installation with the XMTP network. This requires a wallet signature to prove ownership.
3

Create or join a group

Start a new conversation or sync existing groups from the network.
// Sync existing groups from the network
await client.conversations.sync()

// Create a new group
const group = await client.conversations.createGroup(
  [member1Address, member2Address],
  {
    groupName: "Team Discussion",
    groupImageUrl: "https://example.com/avatar.png",
    groupDescription: "Our project coordination channel"
  }
)

console.log('Group created:', group.id())

// List all conversations
const groups = await client.conversations.list()
console.log(`You have ${groups.length} conversations`)
4

Send and receive messages

Exchange end-to-end encrypted messages with group members.
// Send a text message
await group.send("Hello, team! 👋")

// Send with optimistic sending (returns before confirmed)
await group.send("Quick update", { sendOptimistically: true })

// Query recent messages
const messages = await group.findMessages({ limit: 10 })
messages.forEach(msg => {
  console.log(`${msg.senderInboxId}: ${msg.content}`)
})

// Stream new messages in real-time
const stream = await group.streamMessages()
for await (const message of stream) {
  console.log('New message:', message.content)
}
{
  "id": "msg_abc123...",
  "senderInboxId": "0x1234abcd...",
  "senderInstallationId": "install_xyz789...",
  "content": "Hello, team! 👋",
  "sentAtNs": 1234567890000000,
  "kind": "application",
  "deliveryStatus": "published",
  "contentType": {
    "authorityId": "xmtp.org",
    "typeId": "text",
    "versionMajor": 1,
    "versionMinor": 0
  }
}

Next steps

Now that you have LibXMTP running, explore more advanced features:

Managing groups

Add members, update metadata, and configure permissions

Content types

Send reactions, replies, attachments, and custom content

Permissions & policies

Configure who can add members, send messages, and update groups

Consent management

Block unwanted conversations and manage spam

Common patterns

Creating a direct message (DM)

Direct messages are 1:1 conversations with exactly two members:
const dm = await client.conversations.createDm(otherAddress)
await dm.send("Hey! Want to collaborate on this?")

Handling errors

Always wrap LibXMTP operations in try-catch blocks:
try {
  const group = await client.conversations.createGroup([address1, address2])
  await group.send("Welcome!")
} catch (error) {
  if (error.message.includes('not registered')) {
    console.error('One or more addresses are not XMTP users')
  } else {
    console.error('Failed to create group:', error)
  }
}

Syncing conversations

Regularly sync to stay updated with network changes:
// Sync all conversations
await client.conversations.sync()

// Sync a specific group
await group.sync()

Troubleshooting

The first time a client is created, you need to provide a wallet signature to register your installation. Make sure your wallet is properly initialized and can sign messages.See Creating Clients for detailed registration flows.
Messages may take a few seconds to propagate through the network. Use group.sync() to manually fetch new messages, or set up a message stream for real-time updates.
Make sure the dbPath directory exists and is writable by your application. On mobile platforms, use the app’s documents directory.
Users must have an active XMTP installation to be added to groups. They need to have created a client at least once. Check that addresses are valid XMTP users with client.canMessage([address]).

Complete example

Here’s a complete Node.js example that ties everything together:
import { Client } from '@xmtp/node-bindings'

async function main() {
  // Create client
  const client = await Client.create(
    process.env.WALLET_ADDRESS,
    {
      env: 'production',
      dbPath: './my-xmtp-db.db3'
    }
  )
  
  console.log('✅ Client created:', client.inboxId())
  
  // Sync existing conversations
  await client.conversations.sync()
  console.log('✅ Synced conversations')
  
  // Create a group
  const group = await client.conversations.createGroup(
    [process.env.MEMBER_1, process.env.MEMBER_2],
    {
      groupName: "My First Group",
      groupDescription: "Learning LibXMTP"
    }
  )
  
  console.log('✅ Group created:', group.id())
  
  // Send a message
  await group.send("Hello from LibXMTP! 🚀")
  console.log('✅ Message sent')
  
  // Read messages
  const messages = await group.findMessages({ limit: 5 })
  console.log(`📬 Found ${messages.length} messages:`)
  messages.forEach(msg => {
    console.log(`  - ${msg.senderInboxId.slice(0, 10)}...: ${msg.content}`)
  })
  
  // Start streaming new messages
  console.log('👂 Listening for new messages...')
  const stream = await group.streamMessages()
  for await (const message of stream) {
    console.log(`💬 New message from ${message.senderInboxId.slice(0, 10)}...: ${message.content}`)
  }
}

main().catch(console.error)

Resources

Build docs developers (and LLMs) love