Skip to content

Chat app vs chat component

The two packages share most code but exist for different reasons. This page documents the boundary so you know which one to depend on.

In substrate vocabulary: both are Packages (in the docker-for-actors sense — published things, deployable into runtimes, mountable on the bus). The difference is what they expose. @open-matrix/chat exposes a whole vertical app the user opens at /apps/chat/. @open-matrix/chat-component exposes the same conversation engine plus an embeddable surface (<conversation-surface> and friends) so a different vertical's UI can host the conversation pane without owning the chat app.

Identity

Aspect@open-matrix/chat@open-matrix/chat-component
PurposeThe Chat appThe Chat engine + embeddable surface
Manifest appNamechatchat-component
Route prefix/apps/chat//apps/chat-component/
Default nav-order3035
Has webapp blockyesyes
Has surfaces blocknoyes (conversation)
Browser entrydist/browser/register-elements.jssame
Bootstrap entrydist/browser/bootstrap.jssame
Runtime entrydist/runtime/index.jssame
Surface entryn/asrc/surface/register-surface.ts

Component sets

Both packages register the same browser custom elements (verified by reading chat/src/browser/register-elements.ts and chat-component/src/browser/register-elements.ts — they are byte-identical except for import paths):

chat-app, chat-input, chat-message-list, chat-sidebar, chat-header,
chat-session-panel, chat-connection-status, chat-status-bar,
mx-chat-message, mx-code-viewer, mx-markdown-viewer, mx-data-table,
mx-component-browser, mx-activity-trace, mx-theme, mx-split

Both declare the same headless components[] in their matrix.json:

ChatSecurityRealmService, ChatTopicClaimService, ChatConversationProxy,
ChatComponentLibraryProxy, ChatIdentityProxy, ChatPreferencesProxy,
ChatSessionStateProxy, ChatMcpProxy, ChatExportService

This duplication is intentional during the v1 transition. Eventually the packages may share a common engine but the surface boundaries (chat vs. embeddable) are fixed.

What chat-component adds

Only one thing: the surface/ subpath. From chat-component/src/surface/:

FileClassTag
ConversationSurfaceActor.tsConversationSurfaceActor<conversation-surface>
ConversationRenderer.tsConversationRenderer<conversation-renderer>
ConversationInput.tsConversationInput<conversation-input>
ConversationSessionList.tsConversationSessionList<conversation-session-list>
register-surface.ts(function)side-effect register on import

These four elements compose into a slim, embeddable conversation pane that does not include the chat-app shell, sidebar, status bar, or component-browser. It's the conversation surface only — for cross-package embedding.

chat-component/matrix.json:

json
"surfaces": {
  "conversation": {
    "tag": "conversation-surface",
    "module": "./dist/browser/surface/register-surface.js",
    "route": "/apps/chat-component/surface/register-surface.js",
    "description": "Embeddable conversation surface plugin loaded by host shells (Director, etc.) via dynamic import"
  }
}

When to depend on which

  • Building a new host shell that wants a chat surface inside it (like Director's Chat tab): depend on @open-matrix/chat-component and dynamically import '/surface'. See DirectorChatSurfaceHost in the Director package for the canonical pattern.
  • Running the standalone Chat app: install @open-matrix/chat, configure runtime mode, mount the chat-app element.
  • Both: if a Host serves both, the manifests are independent and they mount under different webapp.appNames. They do not collide.

What's not yet split

In a future iteration the two packages might share a @open-matrix/chat-engine core that both depend on, eliminating the duplicated browser/runtime sources. As of 2026-05-05 the duplication is real and lives in src/. Don't try to consolidate this without coordination with WORKSTREAMS/package-structure/ — it is intentional during the dependency-graph stabilization.

See also

Source: projects/matrix-3/packages/chat/matrix.json, projects/matrix-3/packages/chat-component/matrix.json, both src/browser/register-elements.ts, chat-component/src/surface/register-surface.ts.