AI SDK 5 redesigned the message model, and most of what it breaks follows from that. The ai package dropped its React and RSC entrypoints, replaced the data stream API, and renamed or reshaped the types that describe a message. It also renamed the key that holds a tool’s schema and the fields on the parts streamText streams. Upgrade from 4.x and the typecheck fails on the first file that touches any of them.

What changed

Before and after

Renames with no shape change are what Emendant rewrites. This file passes one of them on without calling it, which is why the entry anchors on the import:

import { experimental_wrapLanguageModel, type IDGenerator } from 'ai';
export const wrapped = (model: never, middleware: never) =>
experimental_wrapLanguageModel({ model, middleware });
export function label(generate: IDGenerator): string {
return `msg_${generate()}`;
}
export const wrap = experimental_wrapLanguageModel;

After npx emendant fix:

import { wrapLanguageModel, type IdGenerator } from 'ai';
export const wrapped = (model: never, middleware: never) =>
wrapLanguageModel({ model, middleware });
export function label(generate: IdGenerator): string {
return `msg_${generate()}`;
}
export const wrap = wrapLanguageModel;

The tool rename is one key at each site, and the schema value stays put:

export const weather = tool({
description: 'Look up the weather',
parameters: schema,
execute: async () => ({ temperature: 12 }),
});
export const weather = tool({
description: 'Look up the weather',
inputSchema: schema,
execute: async () => ({ temperature: 12 }),
});

The entrypoint moves are the same edit on the specifier: 'ai/react' becomes '@ai-sdk/react' and 'ai/rsc' becomes '@ai-sdk/rsc'. Three reads off a fullStream part are one word each: part.textDelta becomes part.text, part.args becomes part.input and part.result becomes part.output. The shape changes have no mechanical form: a StreamData route becomes a writer inside createUIMessageStream, and message.content becomes the text parts of message.parts.

Migration guidance and its limits

The ten deterministic patches are safe as offered. The two entrypoint rewrites do not add @ai-sdk/react or @ai-sdk/rsc to your manifest, so install them, or the verification run reports those patches as failing until you do.

The nine assisted changes are the reshapes. Emendant writes them only when you name a model provider, because the right edit depends on how your code reads a message or builds a stream. Two of them turn on the type tag too: argsTextDelta sits in a branch v5 never enters, and experimental_providerMetadata is a rename under step-finish and a removal under finish. Without a provider they are reported with guidance. The assistant API removal and a logprobs read are report only, because nothing in v5 replaces either.

A repository on 6.x or 7.x still writing parameters is reported without --adopted, under a heading saying it is affected today.

Two limits: createIdGenerator now takes its size at creation, which the IdGenerator rename does not touch, and useChat itself changed in 5.0.0 in ways this entry does not describe. A clean scan says a file uses none of the constructs below, nothing more.

What Emendant detects, fixes and verifies

22 changes in ai 5.0.0. 10 patched by a transform, 10 patched only with a model provider you name, 2 report only. Every patch is proved in a copy of your repository before it is offered, and its header names the checks that passed. This table is generated from the feed entry, so it cannot claim more than the entry does.

ChangeSeverityDetectsFixVerified by
The v4 UI message types were replaced by the UIMessage types
ai-npm-5.0.0-message-types-removed
Breaking
  • Message imported from ai
  • CreateMessage imported from ai
Patch, only when you name a model providerYour typecheck and tests
CoreMessage renamed to ModelMessage
ai-npm-5.0.0-coremessage-deprecated
Deprecation
  • CoreMessage imported from ai
Patch, written by the replace-import-specifier transformYour typecheck and tests
The role specific CoreMessage types were renamed
ai-npm-5.0.0-coremessage-role-aliases-deprecated
Deprecation
  • CoreSystemMessage imported from ai
  • CoreUserMessage imported from ai
  • CoreAssistantMessage imported from ai
  • CoreToolMessage imported from ai
Patch, only when you name a model providerYour typecheck and tests
convertToCoreMessages renamed to convertToModelMessages
ai-npm-5.0.0-converttocoremessages-deprecated
Deprecation
  • convertToCoreMessages imported from ai
Patch, written by the replace-import-specifier transformYour typecheck and tests
IDGenerator renamed to IdGenerator
ai-npm-5.0.0-idgenerator-type-renamed
Breaking
  • IDGenerator imported from ai
Patch, written by the replace-import-specifier transformYour typecheck and tests
experimental_wrapLanguageModel became wrapLanguageModel
ai-npm-5.0.0-wraplanguagemodel-stable
Breaking
  • experimental_wrapLanguageModel imported from ai
Patch, written by the replace-import-specifier transformYour typecheck and tests
The ai/rsc entrypoint moved to @ai-sdk/rsc
ai-npm-5.0.0-rsc-subpath-extracted
Breaking
  • any import of ai/rsc
Patch, written by the replace-module-path transformYour typecheck and tests
The ai/react entrypoint was removed
ai-npm-5.0.0-react-subpath-removed
Breaking
  • any import of ai/react
Patch, written by the replace-module-path transformYour typecheck and tests
The data stream API was replaced by UI message streams
ai-npm-5.0.0-data-stream-api-removed
Breaking
  • createDataStream imported from ai
  • createDataStreamResponse imported from ai
  • pipeDataStreamToResponse imported from ai
  • formatDataStreamPart imported from ai
  • parseDataStreamPart imported from ai
  • processDataStream imported from ai
  • StreamData imported from ai
  • DataStreamWriter imported from ai
  • DataStreamOptions imported from ai
  • calls to createDataStream imported from ai
  • calls to createDataStreamResponse imported from ai
  • calls to pipeDataStreamToResponse imported from ai
  • calls to formatDataStreamPart imported from ai
  • calls to parseDataStreamPart imported from ai
  • calls to processDataStream imported from ai
Patch, only when you name a model providerYour typecheck and tests
LangChainAdapter moved to @ai-sdk/langchain
ai-npm-5.0.0-langchain-adapter-moved
Breaking
  • LangChainAdapter imported from ai
Patch, only when you name a model providerYour typecheck and tests
LlamaIndexAdapter moved to @ai-sdk/llamaindex
ai-npm-5.0.0-llamaindex-adapter-moved
Breaking
  • LlamaIndexAdapter imported from ai
Patch, only when you name a model providerYour typecheck and tests
The deprecated CoreTool types were removed
ai-npm-5.0.0-coretool-types-removed
Breaking
  • CoreTool imported from ai
  • CoreToolCall imported from ai
  • CoreToolResult imported from ai
  • CoreToolCallUnion imported from ai
  • CoreToolResultUnion imported from ai
  • CoreToolChoice imported from ai
Patch, only when you name a model providerYour typecheck and tests
The assistant API was removed
ai-npm-5.0.0-assistant-api-removed
Breaking
  • AssistantResponse imported from ai
  • AssistantStatus imported from ai
  • AssistantMessage imported from ai
  • UseAssistantOptions imported from ai
Report onlyNot applicable
ToolInvocation was replaced by typed tool parts
ai-npm-5.0.0-toolinvocation-removed
Breaking
  • ToolInvocation imported from ai
Patch, only when you name a model providerYour typecheck and tests
Attachment was replaced by file parts
ai-npm-5.0.0-attachment-removed
Breaking
  • Attachment imported from ai
Patch, only when you name a model providerYour typecheck and tests
A tool definition names its schema inputSchema instead of parameters
ai-npm-5.0.0-tool-parameters-renamed
Breaking
  • the parameters key in the object passed to tool imported from ai
  • the parameters key under tools.* in the object passed to generateText imported from ai
  • the parameters key under tools.* in the object passed to streamText imported from ai
Patch, written by the rename-property transformYour typecheck and tests
A text-delta part on streamText's fullStream carries text instead of textDelta
ai-npm-5.0.0-fullstream-textdelta-renamed
Breaking
  • .textDelta read on each element iterated through .fullStream from what streamText imported from ai returns
Patch, written by the rename-property transformYour typecheck and tests
Tool parts on streamText's fullStream carry input instead of args
ai-npm-5.0.0-fullstream-args-renamed
Breaking
  • .args read on each element iterated through .fullStream from what streamText imported from ai returns
Patch, written by the rename-property transformYour typecheck and tests
A tool-result part on streamText's fullStream carries output instead of result
ai-npm-5.0.0-fullstream-result-renamed
Breaking
  • .result read on each element iterated through .fullStream from what streamText imported from ai returns
Patch, written by the rename-property transformYour typecheck and tests
experimental_providerMetadata is gone from the parts fullStream yields
ai-npm-5.0.0-fullstream-provider-metadata-removed
Breaking
  • .experimental_providerMetadata read on each element iterated through .fullStream from what streamText imported from ai returns
Patch, only when you name a model providerYour typecheck and tests
logprobs is gone from the parts fullStream yields
ai-npm-5.0.0-fullstream-logprobs-removed
Breaking
  • .logprobs read on each element iterated through .fullStream from what streamText imported from ai returns
Report onlyNot applicable
The tool-call-delta part became tool-input-delta and carries delta instead of argsTextDelta
ai-npm-5.0.0-fullstream-argstextdelta-renamed
Breaking
  • .argsTextDelta read on each element iterated through .fullStream from what streamText imported from ai returns
Patch, only when you name a model providerYour typecheck and tests

emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.

Coverage

Snapshot
2026-09-21.1, sequence 28, signed 21 September 2026
Minimum CLI
emendant@0.1.4
Feed entry
feed/npm/ai/5.0.0.json

emendant feed status shows the snapshot your machine holds, and emendant feed update fetches the latest.

Primary sources

Every claim above was checked against these, each pinned to the release rather than to a default branch.

Scan your repository

Runs locally, reads your lockfile and source, sends nothing anywhere.

npx emendant scan

Then npx emendant fix writes the patches the table says exist. The getting started guide covers the flags and the patch grades.