“Vibe coding” is a term for the increasingly common practice of building software by describing a feature in natural language to an AI, which then generates the code. But it’s not about mind-reading. It’s about learning a new form of technical collaboration.
Getting good at this is a superpower for developers, product managers, and founders. It helps you:
- Scaffold features instantly: Go from a whiteboard sketch to working code in minutes.
- Prototype at the speed of thought: Test ideas without waiting for a full development cycle.
- Lower the barrier to entry: Focus on the “what” and “why” of a feature, letting the AI handle the initial “how.”
The key isn’t just knowing what to ask, but how to ask. A well-structured prompt is the difference between a mess of buggy code and a clean, functional starting point.
The most common reason for poor AI-generated code is a poor prompt. A vague, low-context request will almost always lead to a generic, unhelpful, or incorrect output.
Think of the AI as a brilliant but extremely literal junior developer.
- A bad request: “Hey, can you build me a login page?” This leaves everything open to interpretation—the tech stack, the design, the authentication method, the error handling.
- A good request: “I need a login component for a React application using Formik for state management and Yup for validation. It should have fields for email and password, a ‘Sign In’ button, and display server errors below the form.”
The first is a wish. The second is a specification. To get good code, you need to provide a good spec.
A great prompt provides the same clarity you’d give a human collaborator. It gives the AI everything it needs to make the right decisions. For code generation, a helpful framework is C.O.D.E.—Context, Objective, Definition, and Examples.
This method forces you to think through the problem before you ask for the solution, which is good practice anyway.
Provide the background. The AI needs to know the environment your code will live in.
- Tech stack: What language, frameworks, and important libraries are you using? (e.g., “I’m in a Next.js 14 app with TypeScript and Tailwind CSS.”)
- Existing code or data: What are the shapes of the objects or data structures it will interact with? (e.g., “It will receive a user object that looks like this:
{ id: string, email: string, isAdmin: boolean }
.”) - The user’s goal: What is the end user trying to accomplish with this feature? (e.g., “The user needs to see a list of their projects so they can click to edit one.”)
State exactly what you want the code to do. Be specific and focus on a single responsibility.
- Bad objective: “Make a user dashboard.”
- Good objective: “Write a JavaScript function named
getUserProjects
that takes auserId
as an argument.” - Good objective: “Create a React component named
ProjectList
that displays an array of project objects.”
Define the requirements and constraints. This is where you include the technical details that ensure the code is useful.
- Acceptance criteria: What are the rules? (e.g., “The function must return an empty array if the user has no projects, not null or undefined.”)
- Constraints: Are there any guardrails? (e.g., “This must be a pure function with no side effects.” or “Do not use any external libraries for this function.”)
- Formatting: How should the output be delivered? (e.g., “Provide the output as a single TypeScript file.” or “Include JSDoc comments for all parameters.”)
Show, don’t just tell. Examples are the fastest way to clarify intent and reduce ambiguity.
- For logic: Provide sample inputs and expected outputs. (e.g., “For example, if the input is
[5, 10, 15]
, the output should be30
.”) - For UI: Describe states or provide mock data. (e.g., “When the
isLoading
prop is true, display a spinner. Whendata
is available, render the list.”)
Let’s walk through building a simple UI component using the C.O.D.E. framework.
The initial idea: “I want a progress bar that shows how complete a user’s profile is.”
The low-context, “bad” prompt: “Write the code for a profile completion progress bar.”
This will likely generate a generic HTML/CSS progress bar with hardcoded values—not very useful.
The high-context, “good” prompt:
Prompt
(Context) I’m working in a React application built with Vite, using TypeScript and Tailwind CSS. I have a user object that comes from my backend, which looks like this:
type User = { firstName: string | null; lastName: string | null; profilePictureUrl: string | null; jobTitle: string | null; };
(Objective) I need two things:
- A standalone TypeScript function called
calculateProfileCompletion
.- A React component called
ProfileCompletionCard
that uses the function.(Definition)
For the
calculateProfileCompletion
function:
- It should accept the
user
object as an argument.- It should return a whole number between 0 and 100.
- Each of the four fields (
firstName
,lastName
,profilePictureUrl
,jobTitle
) is worth 25% of the total. A field is “complete” if it’s notnull
or an empty string.For the
ProfileCompletionCard
component:
- It should take the
user
object as a prop.- It should call
calculateProfileCompletion
to get the percentage.- It must display the text “Profile Completion: [percentage]%”.
- It must display a visual progress bar using
div
elements and Tailwind CSS classes. The outerdiv
should have a light gray background, and the innerdiv
’s width should be dynamic based on the percentage.(Examples)
- If
user = { firstName: 'Ana', lastName: 'Gomez', profilePictureUrl: null, jobTitle: null }
, the function should return 50.- If all fields are filled, it should return 100.
This level of detail gives the AI all the information it needs to generate code that is specific, accurate, and immediately usable.
Your first prompt doesn’t have to be your last. The real power of vibe coding comes from the collaborative back-and-forth.
- Start small, then expand: Ask for the core logic first (like the
calculateProfileCompletion
function), then ask for the UI component that uses it. - Ask for one thing at a time: This makes it easier to verify and debug. Once you have a working function, you can ask for the component, then ask for styling, then ask for storybook stories.
- Refine and refactor: Treat the AI as a pair programmer. “This is great, but can you refactor it to use a
Map
instead of a plain object for the field weights?” or “Can you add error handling in case theuser
prop is null?” - Ask it to explain itself: If you don’t understand a piece of code, ask! “Can you explain why you chose to use
Object.values
here?” - Generate tests: Once the code looks good, ask the AI to write unit tests for it using your preferred testing framework. “Write three Jest tests for the
calculateProfileCompletion
function, covering the zero, 50%, and 100% cases.”
Building features like a “profile completion” progress bar starts with having reliable user data. A clear, predictable data model is the first step to writing a good prompt.
Kinde provides secure user management out-of-the-box, giving you a consistent user object from the moment someone signs up. This means you can easily and safely access standard user details like given_name
and family_name
, as well as any custom user profile fields you define. This clean data model makes it much easier to provide the necessary Context to an AI when asking it to build features that depend on a user’s state, roles, or permissions.
Get started now
Boost security, drive conversion and save money — in just a few minutes.