Next.js 15 and the Vercel AI SDK
Welcome! I am Param, and in this course we are going to ship a full-stack AI agent inside one Next.js app. No Python service glued over an HTTP bridge, no separate orchestration layer. Route handler, tools, streaming UI, guardrails, provider swap, and memory all live next to each other in TypeScript.
The app is a chat where an AI agent can plan, call tools, observe results, and reply across several steps. It looks like any other chat on the surface. Underneath, the route handler streams tool calls, the UI renders them inline, the provider is behind a feature flag, and every thread survives a page reload.
# OpenRouter is the default. One key, many models.
LLM_PROVIDER=openrouter
OPENROUTER_API_KEY=your_key_here
OPENROUTER_MODEL=google/gemma-3-12b-it
# You can switch later to OpenAI without touching the tool code:
# LLM_PROVIDER=openai
# OPENAI_API_KEY=your_key_here
# OPENAI_MODEL=gpt-4o-miniOpenRouter is the default gateway so you need only one key to hit many models. We will flip the flag to OpenAI later once the provider abstraction is in place.
Full-stack agent architecture
One Next.js app handles UI, route handler, tools, and memory. The LLM lives behind a provider abstraction.
It comes down to latency and contracts. A Python service over HTTP adds a round trip on every tool call, which matters when the agent chains several steps. On top of that, tool schemas drift. When tools live next to the route handler, the Zod types ARE the contract between LLM and UI, so you cannot ship a schema mismatch. Python still wins for heavy ML workloads, but an agent that mostly orchestrates LLM calls is happier in one TypeScript codebase.
Validation checklist: Setup checklist
Loading practice…