I've been using AI chatbots daily for months now. Claude, ChatGPT, Gemini -- they're all great. But I kept thinking: what would it look like if I built one myself? Not to compete with any of them, obviously, but to understand the plumbing. How does streaming actually work? How do you wire up a model to a frontend that feels responsive? I wanted to get my hands dirty.

So over the past weekend, I sat down and built TuringAI -- a clean, fast AI chat app powered by Kimi K2.5 through NVIDIA NIM. It's open source, it's live on Vercel, and honestly, I'm pretty happy with how it turned out.

Why Build Another Chat App

I know what you're thinking. The world doesn't need another AI chat interface. And you're right. But that wasn't really the point. I wanted to explore Vercel AI SDK v5 and see how it handles streaming with newer models. I also wanted to try Kimi K2.5, which I'd been reading about but hadn't used directly. NVIDIA NIM provides an OpenAI-compatible API for it, which made integration straightforward.

Beyond the technical curiosity, I wanted something minimal. No account creation, no subscription prompts, no bloated sidebars with features I'd never use. Just a text box, a model, and fast responses. Something I could open in a browser tab and start typing immediately.

The Stack

I went with Next.js 15 and TypeScript for the foundation. Tailwind CSS v4 for styling, because at this point I can't imagine writing CSS any other way. The core AI integration runs on Vercel AI SDK v5, which handles the streaming protocol between the client and the API route.

The model itself is Kimi K2.5, accessed through NVIDIA NIM's inference API. I added web search capability using Serper.dev, so the model can ground its answers in real-time information when needed. Conversation history lives in localStorage -- no database, no backend persistence. It keeps things simple and private.

For the UI, I focused on the details that actually matter when you're chatting with an AI: proper code blocks with syntax highlighting and a copy button, a floating input bar that stays anchored at the bottom, a collapsible sidebar for managing conversations, and a dark/light theme toggle that remembers your preference.

The AI SDK v5 Learning Curve

This is where things got interesting. Vercel AI SDK v5 is a significant rewrite from v4. If you've used useChat from the older version, forget most of what you know. The API surface changed substantially. The way you define route handlers, how messages are structured, how tool calls work -- all different.

I spent a good chunk of Saturday debugging streaming issues that turned out to be v5 breaking changes. The documentation is solid but still catching up in some areas. Certain patterns from v4 tutorials and Stack Overflow answers simply don't apply anymore. I had to read the source code more than once to understand how the new streamText function expected its parameters.

The other challenge was getting NVIDIA NIM to play nicely with the SDK. Since NIM exposes an OpenAI-compatible endpoint, I used the OpenAI provider adapter. But there were subtle differences in how Kimi K2.5 handles system prompts and tool calling compared to GPT models. It took some trial and error to get the web search tool integrated cleanly without breaking the streaming flow.

Features I'm Proud Of

The streaming experience feels genuinely snappy. Tokens appear as they arrive, with no awkward buffering or layout shifts. I spent time making sure the auto-scroll behavior works naturally -- it follows the stream but stops if you scroll up to read something, then resumes when you scroll back down.

The web search integration is probably my favorite feature. When the model determines it needs current information, it calls the Serper.dev API, retrieves relevant results, and incorporates them into its response. You can see when it's searching, which adds transparency to the process.

I'm also happy with the conversation management. The sidebar shows your chat history, you can rename conversations, delete ones you don't need, and start fresh with a single click. Everything persists in localStorage, so there's no sign-up wall, no data leaving your browser unless you're actively chatting with the model.

The theme toggle was a small touch but it makes a difference. Dark mode is the default because I built this for myself first, and I live in dark mode. But the light theme is clean and usable too.

What's Next

I'm planning to add support for multiple models so you can switch between different providers within the same interface. I'd also like to experiment with file uploads and image understanding once the model support is there. Maybe a voice input mode down the line.

For now though, TuringAI does exactly what I wanted it to do. It's fast, it's clean, and I understand every line of code in it. Sometimes that's the best reason to build something -- not because the world needs it, but because you need to understand how it works.

The code is up on GitHub and the app is live at turing-ai-one.vercel.app. Try it out or spin up your own instance. PRs welcome.

Update: I've since done a major revamp of TuringAI -- orange neon theme, WebGL sign-in, voice recording, AI-generated titles, and more. Read about it in Revamping TuringAI.