Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/matrix-org/matrix-js-sdk/llms.txt

Use this file to discover all available pages before exploring further.

MatrixClient is the main entry point for the matrix-js-sdk. Every interaction with a Matrix homeserver — syncing, sending events, managing rooms, calling APIs — goes through a single MatrixClient instance. It extends TypedEventEmitter, so your application reacts to state changes and incoming data by registering event listeners rather than polling.

Creating a client

Use the createClient helper exported from matrix-js-sdk. It accepts an ICreateClientOpts object.
import * as sdk from "matrix-js-sdk";

const client = sdk.createClient({
    baseUrl: "https://matrix.org",
    accessToken: "your_access_token",
    userId: "@alice:matrix.org",
    deviceId: "DEVICE_ID",
});

Key options

The base URL of the homeserver, e.g. https://matrix.org. All HTTP requests are made relative to this URL.
The access token to authenticate requests. Omit only if the client will be used unauthenticated (e.g. to list public rooms).
The fully-qualified Matrix user ID (@localpart:server). Required for most authenticated operations.
A unique identifier for this device. Required when end-to-end encryption is enabled — if unset, E2EE is disabled.
An IStore implementation for persisting sync data. Defaults to a MemoryStore if omitted. See Storage for details.
A MatrixScheduler instance for queuing and retrying outbound events. Without one, failed sends are not retried automatically.
A CryptoStore for E2EE session data. Used by the legacy crypto stack and for migration to the Rust crypto backend.
A custom Logger instance. Defaults to the built-in global logger.

Starting and stopping the client

Creating a client does not start syncing. Call startClient() to begin the sync loop, and stopClient() to shut it down.
1

Create the client

const client = sdk.createClient({
    baseUrl: "https://matrix.org",
    accessToken: myAccessToken,
    userId: myUserId,
});
2

Register a sync listener before starting

Register at least a ClientEvent.Sync listener before calling startClient() so you don’t miss the initial PREPARED transition.
client.once(ClientEvent.Sync, (state, prevState, data) => {
    if (state === "PREPARED") {
        console.log("Client ready — rooms:", client.getRooms().length);
    }
});
3

Start the client

await client.startClient({ initialSyncLimit: 10 });
4

Stop the client when done

client.stopClient();

IStartClientOpts

The options object passed to startClient() controls sync behaviour:
OptionTypeDefaultDescription
initialSyncLimitnumber8Number of events to fetch per room on first sync
lazyLoadMembersbooleanfalseDefer loading room members until explicitly requested
pendingEventOrderingPendingEventOrderingchronologicalWhere locally-sent (pending) events appear in the timeline
pollTimeoutnumber30000Milliseconds to hold open each /sync long-poll request
disablePresencebooleanfalseSuppress automatic presence updates
threadSupportbooleanfalseOrganise events into Thread objects when thread relations are found
slidingSyncSlidingSyncPass a SlidingSync instance to use MSC4186 instead of the classic sync API

The event-driven model

MatrixClient extends TypedEventEmitter. Rather than polling the client for new data, register listeners for the events you care about.
import { ClientEvent, RoomEvent, RoomMemberEvent } from "matrix-js-sdk";

// Every raw event received over /sync
client.on(ClientEvent.Event, (event) => {
    console.log("Received event:", event.getType());
});

// Account data changes
client.on(ClientEvent.AccountData, (event, oldEvent) => {
    console.log("Account data updated:", event.getType());
});

// A new room was added (invite or join)
client.on(ClientEvent.Room, (room) => {
    console.log("New room:", room.roomId);
});

// A room was forgotten
client.on(ClientEvent.DeleteRoom, (roomId) => {
    console.log("Room deleted:", roomId);
});

// Typing changes — re-emitted from RoomMember
client.on(RoomMemberEvent.Typing, (event, member) => {
    if (member.typing) {
        console.log(member.name, "is typing...");
    }
});

ClientEvent enum

ValueConstantDescription
"sync"ClientEvent.SyncSync state changed (see Sync)
"event"ClientEvent.EventA live event arrived via /sync
"accountData"ClientEvent.AccountDataUser-scoped account data was updated
"Room"ClientEvent.RoomA new room object was created
"deleteRoom"ClientEvent.DeleteRoomA room was forgotten
"WellKnown.client"ClientEvent.ClientWellKnown.well-known data was fetched
"turnServers"ClientEvent.TurnServersTURN server credentials refreshed
ClientEvent.ToDeviceEvent is deprecated. Use ClientEvent.ReceivedToDeviceMessage instead, which also provides encryption metadata.

Authenticated versus unauthenticated usage

A MatrixClient without accessToken/userId can still make unauthenticated requests such as listing public rooms:
const anonClient = sdk.createClient({ baseUrl: "https://matrix.org" });
const data = await anonClient.publicRooms();
console.log("Public rooms:", data.chunk.length);

Widget embedding

For Matrix widget integrations, use createRoomWidgetClient instead of createClient. It sets up a client pre-wired to communicate over the widget postMessage transport.
import { createRoomWidgetClient } from "matrix-js-sdk";

const widgetClient = createRoomWidgetClient(
    widgetApi,
    capabilities,
    roomId,
    opts,
);
Widgets run inside an iframe alongside a Matrix client; createRoomWidgetClient handles the capability negotiation and postMessage plumbing automatically.