OpenCodex
Back to Blog
May 4, 2026
5 min read

Build an AI Chatbot with DeepSeek and Next.js in 30 Minutes

Step-by-step tutorial to build a production-ready AI chatbot using DeepSeek API and Next.js. Includes streaming, error handling, and deployment.

nextjsdeepseekchatbottutorialreact
Share this article

Build an AI Chatbot with DeepSeek and Next.js

Prerequisites

  • Node.js 18+
  • Next.js 14+
  • DeepSeek API key

Project Setup

npx create-next-app@latest ai-chatbot --typescript --tailwind
cd ai-chatbot
npm install openai

Step 1: Environment Variables

# .env.local
DEEPSEEK_API_KEY=your-api-key-here

Step 2: Create the API Route

// app/api/chat/route.ts
import OpenAI from 'openai';
import { NextRequest } from 'next/server';

const client = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: 'https://api.deepseek.com/v1',
});

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

  const stream = await client.chat.completions.create({
    model: 'deepseek-chat',
    messages,
    stream: true,
  });

  const encoder = new TextEncoder();
  const readable = new ReadableStream({
    async start(controller) {
      for await (const chunk of stream) {
        const text = chunk.choices[0]?.delta?.content || '';
        controller.enqueue(encoder.encode(text));
      }
      controller.close();
    },
  });

  return new Response(readable, {
    headers: { 'Content-Type': 'text/plain; charset=utf-8' },
  });
}

Step 3: Build the Chat UI

// app/page.tsx
'use client';

import { useState, useRef, useEffect } from 'react';

interface Message {
  role: 'user' | 'assistant';
  content: string;
}

export default function ChatPage() {
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);
  const bottomRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  async function sendMessage() {
    if (!input.trim() || loading) return;

    const userMessage: Message = { role: 'user', content: input };
    const newMessages = [...messages, userMessage];
    setMessages(newMessages);
    setInput('');
    setLoading(true);

    const assistantMessage: Message = { role: 'assistant', content: '' };
    setMessages([...newMessages, assistantMessage]);

    const response = await fetch('/api/chat', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ messages: newMessages }),
    });

    const reader = response.body!.getReader();
    const decoder = new TextDecoder();

    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      const text = decoder.decode(value);
      setMessages(prev => {
        const updated = [...prev];
        updated[updated.length - 1].content += text;
        return updated;
      });
    }

    setLoading(false);
  }

  return (
    <div className="flex flex-col h-screen max-w-2xl mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">AI Chatbot (DeepSeek)</h1>

      <div className="flex-1 overflow-y-auto space-y-4 mb-4">
        {messages.map((msg, i) => (
          <div key={i} className={msg.role === 'user' ? 'text-right' : 'text-left'}>
            <div className={
              msg.role === 'user'
                ? 'inline-block bg-blue-500 text-white rounded-lg px-4 py-2 max-w-xs'
                : 'inline-block bg-gray-100 rounded-lg px-4 py-2 max-w-xs'
            }>
              {msg.content}
            </div>
          </div>
        ))}
        <div ref={bottomRef} />
      </div>

      <div className="flex gap-2">
        <input
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={e => e.key === 'Enter' && sendMessage()}
          placeholder="Type a message..."
          className="flex-1 border rounded-lg px-4 py-2"
        />
        <button
          onClick={sendMessage}
          disabled={loading}
          className="bg-blue-500 text-white px-4 py-2 rounded-lg disabled:opacity-50"
        >
          Send
        </button>
      </div>
    </div>
  );
}

Step 4: Run and Test

npm run dev
# Open http://localhost:3000

Step 5: Deploy to Vercel

npm install -g vercel
vercel --prod
# Add DEEPSEEK_API_KEY in Vercel dashboard

Cost Estimate

For a chatbot with 10,000 messages/day (avg 500 tokens each):

  • Daily tokens: 5M
  • Daily cost: ~$0.50 (DeepSeek)
  • Monthly cost: ~$15

Compare to GPT-4: ~$1,500/month

Production Enhancements

  1. Rate limiting: Prevent abuse
  2. Message history: Store in database
  3. System prompt: Customize personality
  4. Error handling: Retry on failures
  5. Auth: Require login for API access

Conclusion

Building an AI chatbot with DeepSeek and Next.js takes under 30 minutes and costs 100x less than GPT-4. The OpenAI-compatible API means you can switch models without changing your code.

Related posts

Try DeepSeek V3 with 500 free Credits.

OpenAI-compatible API, crypto-friendly payments, no phone number required.

Get Started Free