UI Messages vs Model Messages
Overview
Section titled “Overview”AI SDK v6 uses two distinct message types for different purposes. UIMessage is the source of truth for your application state and powers the frontend via useChat. ModelMessage (also called CoreMessage) is the format that gets sent to the LLM provider.
UIMessage carries rich UI data: an id, a role, an array of typed parts (text, tool invocations, sources, files, reasoning, data), and optional metadata. ModelMessage is leaner and provider-oriented, with role values that include 'tool' and content that varies by role.
You convert between the two with convertToModelMessages() (async, UIMessage to ModelMessage) and convertToUIMessages() (ModelMessage to UIMessage). This separation keeps your UI flexible without polluting what the LLM sees.
TypeScript Types
Section titled “TypeScript Types”interface UIMessage<METADATA = unknown> { id: string; role: 'system' | 'user' | 'assistant'; parts: Array<UIMessagePart>; metadata?: METADATA;}
// UIMessagePart variants:// TextUIPart | ToolUIPart | SourceUrlUIPart | FileUIPart// | StepStartUIPart | ReasoningUIPart | DataUIPart// ModelMessage (CoreMessage) — role determines content shapetype ModelMessage = | { role: 'system'; content: string } | { role: 'user'; content: string | Array<UserContentPart> } | { role: 'assistant'; content: string | Array<AssistantContentPart> } | { role: 'tool'; content: Array<ToolResultPart> };Conversion
Section titled “Conversion”import { convertToModelMessages } from '@ai-sdk/ui-utils';import { streamText } from 'ai';
// UIMessage[] -> ModelMessage[] (async)const modelMessages = await convertToModelMessages(uiMessages);
const result = streamText({ model, messages: modelMessages,});import { convertToUIMessages } from '@ai-sdk/ui-utils';
// ModelMessage[] -> UIMessage[]const uiMessages = convertToUIMessages(modelMessages);Key Differences
Section titled “Key Differences”| Aspect | UIMessage | ModelMessage (CoreMessage) |
|---|---|---|
| Used in | Frontend (useChat) | LLM calls (generateText, streamText) |
| Roles | system, user, assistant | system, user, assistant, tool |
| Content | parts array (typed) | Varies by role (string or content parts) |
Has id | Yes | No |
Has metadata | Yes | No |
| Source of truth for | App/UI state | Provider communication |
See also
Section titled “See also”- Challenge 1.3: Generating Text — result object and message handling
- Challenge 4.3: Persistence — storing and restoring UIMessages