Message

A comprehensive suite of components for displaying chat messages, including message rendering, branching, actions, and markdown responses.

Demo

Full-featured example with attachments, branching, and actions.

svelte-5-banner.jpg
How does Svelte 5 runes system work and when should I use them?

Svelte 5 Runes Guide

Svelte 5 introduces runes - a powerful new reactivity system using special $ prefixed functions. Here's what you need to know:$

Core Runes

Creates reactive state in your components:

svelte
<script lang="ts">  let count = $state(0);</script><button onclick={() => count++}>  Count: {count}</button>

Computes values that automatically update when dependencies change:

svelte
<script lang="ts">  let count = $state(0);  let doubled = $derived(count * 2);  let message = $derived.by(() => {    return count > 10 ? 'High!' : 'Low';  });</script>

When to Use Runes

  • Component state - Use $state for reactive variables$
  • Computed values - Use $derived for values based on state$
  • Side effects - Use $effect when needed (but prefer watch() from runed)$
  • Props - Use $props() to declare component props$

Key Benefits

  1. Explicit reactivity - Clear what's reactive vs static
  2. Works everywhere - Runes work in .svelte.ts files too
  3. Better TypeScript - Improved type inference

Would you like to explore $effect, $props, or $bindable?$

Basic Usage

Simple user and assistant messages with markdown content.

How does Svelte 5 runes system work?

Svelte 5 Runes System

Svelte 5 introduces runes - special compiler directives that make reactivity explicit. Here are the core runes:

Core Runes

RunePurpose
$state $Create reactive state
$derived $Compute derived values
$props $Declare component props
$effect $Handle side effects

Quick Example

svelte
<script lang="ts">  let count = $state(0);  let doubled = $derived(count * 2);</script><button onclick={() => count++}>  Count: {count}, Doubled: {doubled}</button>

The key benefit is explicit reactivity - you always know what's reactive vs static.

Would you like to dive deeper into any specific rune?

Installation

pnpm dlx shadcn-svelte@latest add https://svelte-ai-elements.vercel.app/r/new-message.json

If you prefer using jsrepo, please install via the command below:

pnpm dlx jsrepo add @ai/elements/ai-elements/new-message

Features

  • Displays messages from both user and AI assistant with distinct styling and automatic alignment
  • Minimalist flat design with user messages in secondary background and assistant messages full-width
  • Response branching with navigation controls to switch between multiple AI versions
  • File attachments display with file type icons, names, and sizes
  • Action buttons with tooltips for common actions like copy, retry, like, dislike
  • Built-in markdown rendering with syntax highlighting via svelte-streamdown
  • Automatic dark/light theme support via mode-watcher
  • Svelte 5 runes with class-based context for state management

Component Structure

Visual representation of how components are composed together:

With Attachments

Messages with file attachments like images and documents.

svelte-5-runes-demo.jpg
Can you review these files and explain how the component architecture works?

I've analyzed your files. Here's what I found:

File Analysis

📷 svelte-5-runes-demo.jpg

A visual demonstration of the new runes syntax with code examples showing $state and $derived patterns.

📄 component-architecture.pdf

Key Sections:

  • Component hierarchy diagram
  • State management patterns
  • Props flow documentation

📝 notes.txt

Contains quick reference notes for the implementation.

Recommendations

  1. Consider using $props for better type safety$
  2. The component structure follows best practices
  3. State is properly encapsulated

Would you like me to explain any specific part in more detail?

With Branching

Navigate between multiple AI response versions using branch selector.

What's the best way to manage state in Svelte 5?

Option 1: Local State with $state$

The simplest approach for component-local state:

svelte
<script>  let count = $state(0);</script><button onclick={() => count++}>  Clicks: {count}</button>

Best for: Simple counters, toggles, form inputs

With Actions

Action buttons for copy, regenerate, like, and dislike.

Show me a Svelte 5 component with runes

Svelte 5 Component Example

Here's a reactive greeting component using runes:

svelte
<script lang="ts">  let name = $state('World');  let greeting = $derived('Hello, ' + name + '!');</script><div class="card">  <h1>{greeting}</h1>  <input bind:value={name} placeholder="Enter name" /></div>

Key Concepts

RuneUsage in Example
$state $Reactive name variable
$derived $Auto-updating greeting

This pattern is perfect for form inputs and dynamic content!

Usage with AI SDK

Integrate with Vercel AI SDK v5's Chat class for real-time streaming responses.

Add the following component to your frontend:

+page.svelte

Add the following route to your backend:

api/chat/+server.ts

Props

Message

PropTypeDefaultDescription
from'user' | 'assistant'-The role of the message sender
childrenSnippet-Child components (MessageContent, MessageActions, etc.)
classstring-Additional CSS classes

MessageContent

PropTypeDefaultDescription
childrenSnippet-Content to render (typically MessageResponse)
classstring-Additional CSS classes

MessageResponse

PropTypeDefaultDescription
contentstring-Markdown content to render with syntax highlighting
classstring-Additional CSS classes

MessageActions

PropTypeDefaultDescription
childrenSnippet-MessageAction components
classstring-Additional CSS classes

MessageAction

PropTypeDefaultDescription
tooltipstring-Tooltip text shown on hover
labelstring-Accessible label for the action
onclick() => void-Click handler function

MessageBranch

PropTypeDefaultDescription
defaultBranchnumber0Initial branch index to display
childrenSnippet-MessageBranchContent and MessageBranchSelector

MessageBranchContent

PropTypeDefaultDescription
contentT[]-Array of content items to render
renderItemSnippet<[T, number]>-Snippet to render each content item

MessageAttachment

PropTypeDefaultDescription
namestring-File name to display
typestring-MIME type (e.g., 'image/png', 'application/pdf')
sizenumber-File size in bytes
onRemove() => void-Handler called when remove button is clicked