Svelte gets first-class bindings. The shape mirrors React, but the endpoint is a SvelteKit +server.ts file.
Setup:
pnpm add ai @ai-sdk/svelte zod
Server (src/routes/api/chat/+server.ts):
import { convertToModelMessages, createUIMessageStreamResponse, streamText, toUIMessageStream } from 'ai';
import type { RequestHandler } from './$types';
export const POST: RequestHandler = async ({ request }) => {
const { messages } = await request.json();
const result = streamText({
model: 'your-model-id',
instructions: 'You are a helpful assistant.',
messages: await convertToModelMessages(messages),
abortSignal: request.signal,
});
return createUIMessageStreamResponse({ stream: toUIMessageStream({ stream: result.stream }) });
};
Client component:
import { useChat } from '@ai-sdk/svelte';
import { DefaultChatTransport } from 'ai';
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: '/api/chat' }),
});
Checklist:
1. Install @ai-sdk/svelte, not @ai-sdk/react. The hook names are the same (useChat, useObject), the package is framework-specific.
2. SvelteKit endpoints export POST as a RequestHandler in +server.ts. The AI SDK stream helpers return a standard Response, which SvelteKit serves as-is.
3. await convertToModelMessages(messages) on the server, same as every other framework. UIMessage in, ModelMessage out.
4. Use request.signal for abortSignal so navigating away cancels the provider call.
5. The AI Gateway key goes in .env as AI_GATEWAY_API_KEY. SvelteKit loads .env automatically; never import the key into client code.
6. Version note: @ai-sdk/svelte has its own version line (5.x in the v7 era). Install @latest and let it pull the matching ai peer, do not hand-pin ai to a different major.