Message Bubble

A focused conversational surface with visual tones, independent alignment, grouped messages, expandable content, and interactive link or button support.

Animated Surfaces

message-bubble.tsx

An interactive conversation where each newly sent user row pops up once while the assistant streams into a stable row.

What should we include in the first release?
Start with the smallest workflow that still feels complete.

With Avatars

message-bubble.tsx

Progressively arriving messages with sender avatars, metadata, delivery state, and grouped follow-up alignment.

YouNow
Can you turn these notes into a launch update?
Delivered

Show More

message-bubble.tsx

A long assistant message with a compact line-clamped preview and animated disclosure control.

AssistantSummary

The release is ready for a focused rollout. The main conversation flow, keyboard navigation, error recovery, and reduced-motion behavior are all covered.

I would keep advanced workflow controls out of this version. They add configuration without improving the first-run experience, and the usage data from this release will give us a better basis for those decisions.

Before publishing, run the accessibility suite once more and verify the streaming behavior with a long response on a smaller viewport.

API Reference

MessageBubble

variant?
"ghost" | "outline" | "solid" | "danger" | "soft" | "tint"
soft
align?
"end" | "start"

Defaults to the surrounding Message alignment when omitted.

animateIn?
boolean

Plays the bubble entrance once when this component mounts.

false
className?
string

MessageBubbleContent

render?
ReactElement<unknown, string | JSXElementConstructor<any>>

Replaces the content element while preserving bubble styling.

className?
string

MessageBubbleGroup

spacing?
"default" | "compact"
compact
className?
string

MessageBubbleCollapsible

open?
boolean
defaultOpen?
boolean
false
onOpenChange?
((open: boolean) => void)
collapsedLines?
4 | 2 | 3 | 5 | 6
4
moreLabel?
ReactNode
Show more
lessLabel?
ReactNode
Show less
contentClassName?
string
triggerClassName?
string
className?
string

Install

Add it with the shadcn CLI, or copy the source manually.

$ bunx --bun shadcn add @beui/message-bubble

Composition

Place the bubble inside message content so identity and layout remain separate from the visible response surface.

Message
├── MessageAvatar
└── MessageContent
    └── MessageBubble
        └── MessageBubbleContent

Note: Message adds sender alignment, metadata, and avatar placement. Streaming Response provides the active and completed response lifecycle.

How it works

A bubble is the visible surface of one message, not the conversation itself. It should give content a clear reading shape without taking ownership of sender identity, delivery, or scroll behavior.

Updated