Message
Composable chat message primitives for Svelte with markdown responses, attachments, branching, and action slots.
message gives you role-aware layout, markdown rendering, attachments, branching, and action slots in one composable API.
Installation
If you prefer using jsrepo, please install via the command below:
Examples
Basic Example
Render user and assistant messages with markdown output.
Use the primitives in layers:
-
Messagewraps the role-aware shell -
MessageContentrenders a single response body -
MessageResponseadds markdown, code highlighting, mermaid, and math support
Add attachments, branching, or a toolbar only when you need them.
File Attachment Example
Show image and file attachments with the built-in preview dialog.
I can review both:
- Click the image tile to open the centered preview dialog
- Non-image files stay compact and tooltip-based
- You can add
onRemovewhen attachments should be dismissible
Branch Example
Switch between multiple assistant versions with the simplified branching API.
Option 1
Keep it compact and composable. Use Message for layout, MessageContent for a single body, and MessageToolbar only when the message needs controls.
Usage AI SDK
Compose prompt-input with message using a local text-only workflow.
Props
Message
| Name | Type | Default |
|---|---|---|
from | 'user' | 'assistant' | 'system' | 'function' | 'data' | 'tool' | |
children | Snippet | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageContent
| Name | Type | Default |
|---|---|---|
children | Snippet | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageResponse
| Name | Type | Default |
|---|---|---|
content | string | |
components | StreamdownProps["components"] | |
class | string | |
...restProps | Omit<StreamdownProps, "class" | "content" | "components"> | |
MessageToolbar
| Name | Type | Default |
|---|---|---|
children | Snippet | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageActions
| Name | Type | Default |
|---|---|---|
children | Snippet | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageAction
| Name | Type | Default |
|---|---|---|
tooltip | string | |
label | string | |
variant | ButtonVariant | 'ghost' |
size | ButtonSize | 'icon' |
class | string | |
disabled | boolean | |
onclick | (event: MouseEvent) => void | |
...restProps | Omit<ButtonProps, "children" | "type" | "href"> | |
MessageBranch
| Name | Type | Default |
|---|---|---|
defaultBranch | number | 0 |
onBranchChange | (branchIndex: number) => void | |
children | Snippet | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageBranchContent
| Name | Type | Default |
|---|---|---|
versions | { id: string; content: string }[] | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageBranchSelector
| Name | Type | Default |
|---|---|---|
children | Snippet | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageBranchPrevious
| Name | Type | Default |
|---|---|---|
children | Snippet | |
class | string | |
...restProps | Omit<ButtonProps, "children" | "type" | "href"> | |
MessageBranchNext
| Name | Type | Default |
|---|---|---|
children | Snippet | |
class | string | |
...restProps | Omit<ButtonProps, "children" | "type" | "href"> | |
MessageBranchPage
| Name | Type | Default |
|---|---|---|
children | Snippet | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageAttachments
| Name | Type | Default |
|---|---|---|
children | Snippet | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageAttachment
| Name | Type | Default |
|---|---|---|
data | { type: "file"; filename?: string; mediaType?: string; url?: string } | |
onRemove | () => void | |
class | string | |
...restProps | HTMLAttributes<HTMLDivElement> | |
MessageAttachmentPreview
| Name | Type | Default |
|---|---|---|
data | { type: "file"; filename?: string; mediaType?: string; url?: string } | |
class | string | |