← Back to list

Build and Deploy an AI Tool in Minutes with Codeium

2. Set Up Codeium / Windsurf Environment

REIT monero · 2026-05-31 02:12 · 0 claps · 3.2 min read
#windsurf-ai #codeium
Open on Medium ↗
Wiki topics: AI · AI · General

Build and Deploy an AI Tool in Minutes with Codeium

2. Set Up Codeium / Windsurf Environment

Step 1 — Install IDE

Install Windsurf IDE (Codeium-based):

Step 2 — Enable AI Agent Mode

Inside Windsurf:

  • Open AI chat panel
  • Switch to “Agent” or “Chat with context”
  • This allows multi-file generation

3. Generate Project Skeleton Using AI

Instead of manually scaffolding, prompt Codeium like:

“Create a Next.js 14 app with a simple AI text summarizer page. Include API route /api/summarize that calls OpenAI API. Use Tailwind for UI.”

At this stage, you already have ~70–80% of a working tool.

4. Add AI Functionality (Core Logic)

Example architecture

Frontend flow: User input → UI → API route → LLM → response → UI

API route (conceptual)

Your AI endpoint will:

  1. receive prompt text
  2. send it to model API
  3. return structured result

You typically instruct Codeium:

“Implement server route that sends user text to OpenAI Chat Completions API and returns summary only.”

6. Local Testing

Run:

npm install
npm run dev

Use Codeium to fix bugs:

“Fix error: API route returning 500 when input is empty”

7. Prepare for Deployment

Before deploying:

Add environment variables

Create .env.local:

OPENAI_API_KEY=your_key_here

Ensure Codeium has not hardcoded secrets.

Check build readiness:

npm run build

8. Deploy in 2–3 Minutes (Vercel Path)

Use Vercel (fastest for Next.js):

Push code to GitHub:

git init
git add .
git commit -m "AI tool MVP"
git push origin main

5.2 Connect frontend to backend

Use:

  • fetch / axios POST to /chat

6. Add Real “AI Tool” Features (What Makes It Useful)

6.3 Structured outputs

Instead of plain text:

{
  "answer": "...",
  "sources": [...],
  "confidence": 0.87
}

7. Testing Locally

Run:

Backend:

uvicorn main:app --reload

Frontend:

npm run dev

“Generate pytest tests for FastAPI /chat endpoint”

Option: Docker-based (production-grade)

Create:

Dockerfile
docker-compose.yml

9. Environment Variables & Secrets

Never hardcode:

  • API keys
  • DB credentials

Use:

  • .env
  • platform secrets manager

Example:

OPENAI_API_KEY=xxx
DATABASE_URL=xxx

It is a simple AI chat app:

  • Backend: FastAPI (Python)
  • Frontend: React (Vite)
  • AI: OpenAI API (swapable)
  • Function: user chats → AI responds

🧠 PROJECT STRUCTURE

ai-tool/
├── backend/
│   ├── main.py
│   ├── requirements.txt
│   └── .env
└── frontend/
    ├── src/
    │   ├── App.jsx
    │   └── main.jsx
    ├── index.html
    ├── package.json
    └── vite.config.js

🚀 BACKEND (FastAPI)

1. backend/requirements.txt

fastapi
uvicorn
python-dotenv
openai
pydantic

2. backend/.env

OPENAI_API_KEY=your_api_key_here

3. backend/main.py

from fastapi import FastAPI
from pydantic import BaseModel
from dotenv import load_dotenv
import os
from openai import OpenAI
from fastapi.middleware.cors import CORSMiddleware
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
app = FastAPI()
# Allow frontend access
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
class ChatRequest(BaseModel):
    message: str
@app.post("/chat")
def chat(req: ChatRequest):
    try:
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": req.message}
            ]
        )
        return {
            "reply": response.choices[0].message.content
        }
    except Exception as e:
        return {"error": str(e)}

▶ Run backend

cd backend
pip install -r requirements.txt
uvicorn main:app --reload

Backend runs at:

http://localhost:8000

💻 FRONTEND (React + Vite)

1. Create project

npm create vite@latest frontend
cd frontend
npm install

2. frontend/package.json (add nothing special except ensure react exists)

Vite already sets this up.

Install fetch helper (optional):

npm install

3. frontend/src/main.jsx

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

4. frontend/src/App.jsx

import { useState } from "react";
export default function App() {
  const [message, setMessage] = useState("");
  const [chat, setChat] = useState([]);
  const [loading, setLoading] = useState(false);
  const sendMessage = async () => {
    if (!message.trim()) return;
    const userMessage = { role: "user", text: message };
    setChat((prev) => [...prev, userMessage]);
    setMessage("");
    setLoading(true);
    try {
      const res = await fetch("http://localhost:8000/chat", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ message })
      });
      const data = await res.json();
      const aiMessage = {
        role: "ai",
        text: data.reply || data.error || "Error"
      };
      setChat((prev) => [...prev, aiMessage]);
    } catch (err) {
      setChat((prev) => [
        ...prev,
        { role: "ai", text: "Backend error" }
      ]);
    }
    setLoading(false);
  };
  return (
    <div style={styles.container}>
      <h2>AI Chat Tool</h2>
      <div style={styles.chatBox}>
        {chat.map((c, i) => (
          <div
            key={i}
            style={{
              ...styles.message,
              alignSelf: c.role === "user" ? "flex-end" : "flex-start",
              backgroundColor: c.role === "user" ? "#DCF8C6" : "#eee"
            }}
          >
            {c.text}
          </div>
        ))}
        {loading && <div style={styles.loading}>Thinking...</div>}
      </div>
      <div style={styles.inputBox}>
        <input
          value={message}
          onChange={(e) => setMessage(e.target.value)}
          style={styles.input}
          placeholder="Type message..."
        />
        <button onClick={sendMessage} style={styles.button}>
          Send
        </button>
      </div>
    </div>
  );
}
const styles = {
  container: {
    maxWidth: 600,
    margin: "40px auto",
    fontFamily: "Arial"
  },
  chatBox: {
    border: "1px solid #ddd",
    height: 400,
    padding: 10,
    display: "flex",
    flexDirection: "column",
    overflowY: "auto",
    marginBottom: 10
  },
  message: {
    padding: 10,
    borderRadius: 10,
    margin: "5px 0",
    maxWidth: "70%"
  },
  inputBox: {
    display: "flex",
    gap: 10
  },
  input: {
    flex: 1,
    padding: 10
  },
  button: {
    padding: "10px 20px",
    cursor: "pointer"
  },
  loading: {
    fontStyle: "italic"
  }
};

▶ Run frontend

cd frontend
npm install
npm run dev

Frontend runs at:

http://localhost:5173

🔗 HOW IT WORKS

Flow:

React UI → FastAPI backend → OpenAI API → response → UI updates

메타데이터
post_id
12e4048e5933
slug
build-and-deploy-an-ai-tool-in-minutes-with-codeium-12e4048e5933
url
https://medium.com/@juricavoda/build-and-deploy-an-ai-tool-in-minutes-with-codeium-12e4048e5933
canonical_url
https://medium.com/@juricavoda/build-and-deploy-an-ai-tool-in-minutes-with-codeium-12e4048e5933
author_url
https://medium.com/@juricavoda
status
ok
fetched_at
2026-06-09 15:37:30