Creating My First AI Cursor: A Beginner's Guide


What is an AI cursor ? How is it beneficial for a web developer ?
An AI cursor is a coding assistant which helps in development and debugging of apps/websites . It is a very modern and robust technique which can boost your efficiency significantly and can probably save a lot of useful time of yours . Being a web dev myself , I used AI for writing code and debugging the errors . Due to the rapid rise of technology in AI fields , We as programmers should be ready to adapt to new modern techniques .
Tech-Stack Used in My AI-Cursor:
Next.js
OpenAI API key
Tailwind CSS
Editor UI: Monaco Editor
Here is a quick SnapShot of my project :
For eg โ You give a prompt like create a TODO app using react and tailwind . It would generate a code and provide you within seconds.
The Idea ๐ก:
I got this innovative and robust idea while wandering through the features of GPT and OpenAI . I found out that we could create our own projects using GPT models . This gave me a wonderful idea of creating my own website using AI .
System Architecture :
User types in a prompt
Prompt + history sent to backend
OpenAI processes it โ returns code
Code is displayed in editor
File Structure:
Backend Logic :
Initialising Next js Request and Response and importing OpenAI API key :
import { NextRequest, NextResponse } from 'next/server';
import OpenAI from 'openai';
// Initialize OpenAI client
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
Connecting with OpenAI : Sending and receiving request and responses :
export async function POST(request: NextRequest) {
try {
const { prompt, history } = await request.json();
if (!prompt) {
return NextResponse.json(
{ error: 'Prompt is required' },
{ status: 400 }
);
}
// Verify that the OpenAI API key is configured.
if (!process.env.OPENAI_API_KEY) {
console.error('OpenAI API key not configured');
return NextResponse.json(
{ error: 'OpenAI API key not configured' },
{ status: 500 }
);
}
// Create the system prompt for code generation
const systemPrompt = `You are an expert software developer. Generate clean, production-ready code based on the user's request.
Requirements:
- Write clean, well-commented code
- Follow best practices and modern conventions
- Include proper error handling
- Use TypeScript when appropriate
- Return only the code, no explanations unless specifically requested
- If the request is unclear, ask for clarification or make reasonable assumptions
Use chain of thought to generate code like follow these steps before generating the code
1) Plan
2) Think
3) Validate
4) Output
For Example :
Prompt-> "User" : Generate a snake game using react
#Plan "Assistant" : The user wants to create a snake game using react . I will prepare a plan for the best output in accordance with the users prompt
#Think "Assistant" : For creating a snake game i have to first compute the list of the resources required . try to go through react documentation and get all required latest code files . I have to make the project typesafe and start generating code
#Validate "Assistant" : Once the code is being generating . start looking for any discrepancies / bugs and look for best solutions . Do not present the output yet.
#Output "Assitant" : Generate the code output in this stage
`;
// Build the messages array, including history if provided
type Message = { role: 'system' | 'user' | 'assistant'; content: string };
let messages: Message[] = [
{
role: "system",
content: systemPrompt
}
];
// If history is provided and is an array, append it
if (Array.isArray(history)) {
// Each item should be { role: 'user' | 'assistant', content: string }
messages = messages.concat(
history
.filter((msg: any) => msg && typeof msg.role === 'string' && typeof msg.content === 'string')
.map((msg: any) => ({
role: msg.role === 'user' || msg.role === 'assistant' ? msg.role : 'user',
content: msg.content
}))
);
}
// Add the latest user prompt
messages.push({
role: "user",
content: `Generate code for: ${prompt}`
});
// Call OpenAI API
const completion = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: messages as any, // OpenAI SDK expects ChatCompletionMessageParam[]
temperature: 0.3, // Lower temperature for more consistent code generation
max_tokens: 2000,
});
const generatedCode = completion.choices[0]?.message?.content || '// No code generated';
return NextResponse.json({
code: generatedCode,
prompt: prompt,
history: [
...(Array.isArray(history) ? history : []),
{ role: "user", content: `Generate code for: ${prompt}` },
{ role: "assistant", content: generatedCode }
]
});
} catch (error) {
console.error('Error generating code:', error);
// Handle specific OpenAI errors
if (error instanceof Error) {
if (error.message.includes('API key')) {
return NextResponse.json(
{ error: 'Invalid OpenAI API key' },
{ status: 401 }
);
}
if (error.message.includes('quota')) {
return NextResponse.json(
{ error: 'OpenAI API quota exceeded' },
{ status: 429 }
);
}
}
return NextResponse.json(
{ error: 'Failed to generate code!' },
{ status: 500 }
);
}
}
FrontEnd Logic :
"use client";
import { useState } from "react";
import { CodeEditor } from "@/components/CodeEditor";
export default function Home() {
const [prompt, setPrompt] = useState("");
const [isGenerating, setIsGenerating] = useState(false);
const [generatedCode, setGeneratedCode] = useState("");
const [history, setHistory] = useState<{ role: string; content: string }[]>([]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!prompt.trim()) return;
setIsGenerating(true);
const newUserMessage = { role: "user", content: prompt };
const updatedHistory = [...history, newUserMessage];
try {
const response = await fetch("/api/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ prompt, history: updatedHistory }),
});
if (response.ok) {
const data = await response.json();
const assistantMessage = { role: "assistant", content: data.code || "// No code generated" };
setGeneratedCode(data.code || "// Generated code will appear here");
setHistory([...updatedHistory, assistantMessage]);
} else {
const errorMsg = "// Error generating code. Please try again.";
setGeneratedCode(errorMsg);
setHistory([...updatedHistory, { role: "assistant", content: errorMsg }]);
}
} catch (error) {
const errorMsg = "// Error generating code. Please try again.";
setGeneratedCode(errorMsg);
setHistory([...updatedHistory, { role: "assistant", content: errorMsg }]);
} finally {
setIsGenerating(false);
setPrompt("");
}
};
History Logic is simple โ FrontEnd will pass prompt and history , history will be of the form of array of {role : string , content : string} . If this array would exist , we will simply append this to our messages array and the AI agent will now store the history of the context . This allows user to re-prompt after getting a response .
More Optimisation and Future Additions :
Add Debounced Query
Add Speech to text prompt
Add Image addition , image generation through GPT-4o model
GitHub Repo Link:
Subscribe to my newsletter
Read articles from Aarush Gupta directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
