ai-ui-patterns
Teaches design patterns for building AI-powered React interfaces. Use when creating chatbots, intelligent assistants, streaming UIs, or any AI-driven user experience in React.
What this skill does
# AI UI Patterns
## Table of Contents
- [When to Use](#when-to-use)
- [Instructions](#instructions)
- [Details](#details)
- [Source](#source)
Building AI-powered interfaces – from chatbots to intelligent assistants – requires careful integration of backend AI services with reactive UI components. In this chapter, we explore design patterns in React for such interfaces, focusing on **two implementations**: a plain React app (using Vite) and a Next.js app. We'll use **OpenAI's API** (via the Vercel AI SDK) as our AI engine, and TailwindCSS for styling. Key topics include prompt management, streaming responses, input debouncing, error handling, and how these patterns differ between Vite and Next.js. We also highlight reusable component patterns and **Vercel's AI UI components (AI Elements)** for building polished chat UIs.
## When to Use
- Use this when building conversational AI interfaces that stream responses from LLMs
- This is helpful for integrating OpenAI, Anthropic, or other AI providers into React applications
- Use this when you need patterns for prompt management, streaming, error handling, and AI-specific UI
## Instructions
- Use the Vercel AI SDK's `useChat` hook for managing conversation state and streaming responses
- Keep API keys on the server — use Next.js API routes or a separate backend for AI calls
- Enable streaming (`stream: true`) for responsive real-time output in chat interfaces
- Debounce input for autocomplete features; disable input during response streaming for chat
- Build reusable components (ChatMessage, InputBox) decoupled from data-fetching logic
## Details
> **Note:** While this article uses OpenAI as an example, the Vercel AI SDK supports multiple model providers including **Gemini**, **OpenAI**, and **Anthropic**. You can easily swap between providers through the SDK's unified interface – we're just choosing one option for demonstration purposes.
### Introduction: AI Interfaces in React
AI-driven user interfaces (UIs) have become popular with the rise of LLMs like ChatGPT. Unlike traditional UIs, AI interfaces often involve conversational interactions, dynamic content streaming, and asynchronous backend calls. This introduces unique challenges and patterns for React developers. A typical AI chat interface consists of a **frontend** (for user input and displaying responses) and a **backend** (to call the AI model). The backend is essential to keep API keys and heavy processing off the client for security and performance. Tools like Vercel's **AI SDK** make it easier to connect to providers (OpenAI, HuggingFace, etc.) and stream responses in real-time. We'll explore how to set up both a Next.js app and a Vite (React) app to handle these concerns, and discuss best practices that apply to both.
**Key patterns covered:**
- Structuring AI prompt data and managing conversation state
- Streaming AI responses to the UI for real-time feedback
- Debouncing user input to avoid spamming the API
- Error handling and fallbacks in the UX
- Reusable UI components for messages, inputs, and more (with TailwindCSS)
- Architectural differences: Next.js route handlers vs. Vite with a Node backend
By the end, you'll be equipped to build a responsive, robust AI-powered UI in React, whether you prefer Next.js or a Vite toolchain.
### Project Setup and Tools
Before diving into code, ensure you have the necessary packages and configurations:
- **React & Vite:** Initialize a Vite + React project (e.g. `npm create vite@latest my-ai-app -- --template react`). For Next.js, you can use `npx create-next-app` or the Next 13 App Router templates. Both will work – we'll highlight differences as we go.
- **TailwindCSS:** Set up Tailwind in your project for quick styling.
- **OpenAI API & Vercel AI SDK:** Install OpenAI's library or the Vercel AI SDK. We will use **Vercel's AI SDK** (`npm i ai`) which provides helpful React hooks (`useChat`, `useCompletion`) and server utilities. This SDK is framework-agnostic, working with Next.js, vanilla React, Svelte, and more. It simplifies streaming and state management, and is free/open-source.
- **API Keys:** Get your OpenAI API key from the OpenAI dashboard and store it safely. In Next.js, put it in `.env.local` (e.g. `OPENAI_API_KEY=sk-...`) and never commit it. In a Vite app, **do not** expose the key in client code – instead, use a backend proxy or environment variable on the server.
### Setting Up AI Endpoints (Next.js vs. Vite)
**Next.js Implementation:** Next.js allows us to create **route handlers** as serverless functions. We can define an API route that the React front-end will call for AI responses:
```typescript
// app/api/chat/route.ts (Next.js)
import { Configuration, OpenAIApi } from 'openai-edge';
import { OpenAIStream, StreamingTextResponse } from 'ai';
export const runtime = 'edge';
const config = new Configuration({ apiKey: process.env.OPENAI_API_KEY });
const openai = new OpenAIApi(config);
export async function POST(req: Request) {
const { messages } = await req.json();
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
stream: true,
messages: messages.map((m: any) => ({ role: m.role, content: m.content }))
});
const stream = OpenAIStream(response);
return new StreamingTextResponse(stream);
}
```
In this handler, we receive a JSON body containing an array of messages (chat history). We call OpenAI's chat completion with `stream: true` to get a streaming response. We then wrap the response in a `StreamingTextResponse` provided by the AI SDK to pipe it back to the client in chunks. The Next.js API route keeps our API key on the server and streams data efficiently.
**Vite (React) Implementation:** In a Vite app, there's no built-in server, so we need to create our own backend for the OpenAI calls. This can be a simple Node/Express server:
```javascript
// backend/server.js (Node/Express for Vite app)
import express from 'express';
import { Configuration, OpenAIApi } from 'openai';
const app = express();
app.use(express.json());
const config = new Configuration({ apiKey: process.env.OPENAI_API_KEY });
const openai = new OpenAIApi(config);
app.post('/api/chat', async (req, res) => {
try {
const { messages = [] } = req.body;
const systemMsg = { role: 'system', content: 'You are a helpful assistant.' };
const inputMessages = [systemMsg, ...messages];
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
stream: false,
messages: inputMessages
});
const content = response.data.choices[0].message?.content;
res.json({ content });
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Internal Server Error' });
}
});
app.listen(6000, () => console.log('API server listening on http://localhost:6000'));
```
During development, you can configure the Vite dev server to proxy `/api` calls to this backend (e.g. in `vite.config.js`, set `server.proxy['/api'] = 'http://localhost:6000'`). The key is that the React app calls a **relative `/api/chat` endpoint**, which the proxy/hosting will route to your server code. This keeps the OpenAI key hidden.
**Enabling Streaming in Node:** The above Express example returns the full response after completion (`stream: false` for simplicity). To stream in Node, you can use OpenAI's HTTP stream: set `stream: true` and handle the response as a stream of data. This involves reading the `response.data` stream and flushing chunks to the client with `res.write()`. If you choose to stick with full responses (no streaming), the UI patterns still largely apply – but streaming greatly improves UX.
### Prompt Handling and Conversation State
At the heart of any AI interface is **prompt management** – assembling user input (and context) into a prompt or message sequence for the AI model. In a chat scenario, we maintain a list of messages, each with a role and content. OpenAI's Chat API expects messages in tRelated in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.