How to Build an AI Chat Interface with Vercel AI SDK and shadcn/ui (2026 Guide)

Why AI Chat Interfaces Are Deceptively Hard to Build


Open almost any modern AI product and you'll see the same familiar layout: a scrolling message list, a text input pinned to the bottom, and tokens streaming in one at a time. It looks simple. Building it well is anything but.


Behind that clean surface, you're managing streaming state, partial tokens, tool calls, retries, markdown rendering, scroll anchoring, and a dozen nuanced UX details—all while keeping the interface accessible and fast. Choose the wrong tooling and you'll spend more time fighting state bugs than shipping your actual product.


In 2026, two tools have become the de facto pairing for this work: the Vercel AI SDK for streaming and model logic, and shadcn/ui for the interface layer. They complement each other almost perfectly, and in this tutorial, you'll use both to build a production-quality AI chat screen.


By the end, you'll have a working chat interface that streams responses, renders markdown, and actually looks like something you'd ship. We'll also touch on how an MCP server can accelerate the UI side further, and where to grab a production-ready template if you'd rather skip the setup.


What we'll build: a streaming AI chat interface with markdown rendering, scroll management, and a polished shadcn/ui-driven design.



Table of Contents





Prerequisites


Before you begin, make sure you have:


  • Node.js 20+ (Node 22 LTS recommended as of 2026)
  • A working Next.js project (we'll scaffold one in Step 1)
  • pnpm, npm, or bun available
  • Basic familiarity with React and TypeScript
  • An API key for an LLM provider (OpenAI, Anthropic, or any AI SDK-compatible provider)



What You'll Build


A fully functional AI chat interface featuring:


  • Token-by-token streaming responses via the Vercel AI SDK
  • Markdown rendering for rich assistant replies (code blocks, lists, links)
  • Auto-scrolling that respects user scroll position
  • Tool call display ready for agent-style workflows
  • Polished shadcn/ui components—buttons, inputs, scroll areas, and avatars
  • An accessible, keyboard-friendly layout



Step 1: Scaffold the Next.js App


Start by creating a fresh Next.js project with the App Router. The App Router gives you server components, streaming, and route handlers out of the box—all of which play nicely with the AI SDK.


pnpm create next-app@latest ai-chat-app --typescript --tailwind --app --eslint
cd ai-chat-app

This sets up TypeScript, Tailwind CSS, and the App Router in one shot. Tailwind is important here because shadcn/ui is built on top of it, so you get consistent styling across your custom chat UI.


Once installed, run the dev server to confirm everything works:


pnpm dev



Step 2: Install the Vercel AI SDK


The Vercel AI SDK has become the standard abstraction for streaming LLM responses in 2026. It normalizes provider APIs, handles stream parsing, and includes React hooks that eliminate almost all of the boilerplate you'd otherwise write.


Install the core package and the React helpers:


pnpm add ai @ai-sdk/react
pnpm add @ai-sdk/openai

Swap @ai-sdk/openai for your preferred provider package (@ai-sdk/anthropic, @ai-sdk/google, etc.)—the API surface stays nearly identical.


Next, create a route handler that streams responses from your model:


// app/api/chat/route.ts
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: openai('gpt-4o-mini'),
    messages,
  });

  return result.toDataStreamResponse();
}

That's the entire backend. The AI SDK handles the wire protocol, partial token delivery, and reconnection logic for you.




Step 3: Why shadcn/ui Pairs So Well with AI Chat UIs


AI chat interfaces have a specific set of UI requirements that map unusually well to shadcn/ui's design philosophy:


| Requirement | Why shadcn/ui Fits |

| --- | --- |

| Customizable message bubbles | Components are copied into your repo, so you can edit them freely |

| Scroll containers | The ScrollArea primitive handles overflow cleanly |

| Accessible inputs | Built on Radix UI, so ARIA attributes come baked in |

| Consistent theming | Tailwind tokens make light/dark modes trivial |

| Composable layout | Primitives like Card, Avatar, and Button snap together fast |


Unlike a traditional component library, shadcn/ui doesn't hide logic behind an abstraction. You own the code, which matters enormously when you need to tweak hover states, timestamps, or streaming cursor behavior.




Step 4: Set Up shadcn/ui in Your Project


Initialize shadcn/ui with the CLI:


pnpm dlx shadcn@latest init

When prompted, choose a base color (Neutral or Zinc both look great for chat UIs) and accept the default CSS variables setup.


Then add the components you'll need for the chat interface:


pnpm dlx shadcn@latest add button input scroll-area avatar card textarea

Each component lands directly in components/ui/—your repo, your rules.




Next Steps


You now have the full foundation for a streaming, markdown-capable AI chat interface:


  1. A Next.js App Router project styled with Tailwind
  2. The Vercel AI SDK wiring up streaming from your model of choice
  3. shadcn/ui components ready to compose into a polished chat screen

  4. From here, the natural extensions are:


    • Wire up the React hook (useChat) on the client and connect it to /api/chat
    • Render markdown with react-markdown and remark-gfm for code blocks and tables
    • Add auto-scroll logic that pauses when the user scrolls up
    • Introduce tool calls for agent-style workflows (function calling, retrieval, MCP servers)
    • Grab a production-ready template if you'd rather skip the plumbing—plenty of shadcn/ui + AI SDK starters exist in 2026 that ship with retries, persistence, and multi-model support

    The combination of the Vercel AI SDK and shadcn/ui removes nearly all the friction that used to make AI chat UIs painful. What's left is the fun part: designing the experience your users will actually love.

    via FreeCodeCamp

Related