# Your AI Assistant Is Only as Useful as Your Last Sentence

## Introduction

When I first started using tools like Cursor, Claude or ChatGPT for frontend development, I expected magic. I thought I could just highlight a buggy snippet, slap on a comment like:

> *Fix this*

…and the AI would instantly understand everything: my tech stack, styling conventions, component logic, even the bugs I hadn’t diagnosed yet.

What I got instead? Half working suggestions. Sometimes vaguely helpful, other times flat out broken. It was like working with someone who knew how to type but not how to think.

Then it clicked.

These tools aren’t your senior engineer, they’re your fastest junior hire. They work fast, but you need to be precise.

Everything changed when I started applying **prompt engineering principles** to frontend work. Here’s exactly how I did it and how you can too.

---

## 1\. Set the Stage: Provide Context Like You are Pairing

Context is your most powerful tool. Even though Cursor can see your file, it can’t read your mind.

Imagine asking a junior dev to help with a bug and only saying:

> *"Can you fix this?"*

They would stare back at you: *What is “this”? What is broken? What’s the expected result?*

AI works the same way. It doesn't know your framework, your styling system or whether you’re in a client or server component unless you tell it.

### 🚫 Bad Prompt:

```plaintext
Fix this useEffect
```

### ✅ Good Prompt:

```plaintext
This is a React client component using useState and useEffect.
It fetches user data by ID, but runs twice in development due to React 18 Strict Mode.
Prevent double-fetching. Use a flag or AbortController. No external state management libs.
```

### Why This Works:

* Specifies the environment: React 18 + dev mode quirks
    
* Defines the goal: fetch only once
    
* Lists constraints: no state libraries
    
* Mentions framework and component type
    

With this, the AI suggested a clean fix: a `useRef` flag, proper cleanup, and fetch control. It worked first try.

### Another Example:

### Prompt:

```plaintext
I’m using Next.js 14 App Router with Server Components.
Convert this client component to use a server action to handle form submission.
The form sends name + email and shows a success toast.
```

### Result:

Cursor created a server action, updated the form to `useFormState`, passed it correctly into the client component and added toast logic using `useEffect`.

## 2\. Define the Goal: Tell the AI What "Better" Means

“Improve this component” is not a prompt. It’s a hope :). Your idea of “better” might mean:

* More readable
    
* More performant
    
* Smaller bundle
    
* Idiomatic to your stack
    

Unless you **define the success criteria**, the AI will make assumptions. And you might not like them.

> Vague adjectives = vague output.

Let’s say you have a clunky card component:

```xml
<div>
  <div style={{ padding: 10, border: "1px solid #ccc" }}>
    <h2>{title}</h2>
    <p>{description}</p>
  </div>
</div>
```

### 🚫 Bad Prompt:

```plaintext
Optimize this component
```

### Result:

AI might add unnecessary flex layout or wrap everything in a grid for no reason and inline more styles.

### ✅ Good Prompts (with clear goals):

```plaintext
Improve readability and styling. Use Tailwind.
Add padding, shadow, rounded corners, and hover transition.
Make it responsive and mobile-friendly.
```

### Result:

```xml
<div className="max-w-sm p-4 rounded-lg shadow-md bg-white hover:scale-105 transition-transform">
  <h2 className="text-lg font-bold">{title}</h2>
  <p className="text-gray-600">{description}</p>
</div>Each of these tells the AI:
```

### Why this works:

* Mention multiple axes:
    
    * **"Use Tailwind"** - you tell it how to style
        
    * **"Improve readability"** - guides semantic naming
        
    * **"Add hover transition"** - you define UX behavior
        
    * **"Responsive"** - it might add `max-w`, `sm:`, `md:` classes
        
    
    In short: you removed ambiguity.
    

## 3\. Split Complex Tasks Into Promptable Steps

Don’t ask the AI to build Rome in one prompt. Think like a developer: break features into components.

> Prompt like you write code: **component-first, feature-later**.

### 🚫 Bad Prompt:

```plaintext
Build a responsive product list with filters, search, sorting and pagination
```

The AI would:

* Add everything into one massive component
    
* Mix up loading and UI logic
    
* Miss the styling system I used (Tailwind)
    

### ✅ Good Prompts (step by step)

#### Step 1: Basic fetch

```plaintext
Create a component that fetches products from /api/products and displays them
```

```javascript
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
  fetch('/api/products')
    .then(res => res.json())
    .then(setProducts)
    .finally(() => setLoading(false));
}, []);
```

#### Step 2: Search

```plaintext
// Add a search input that filters products by name (case-insensitive)
```

```javascript
const [query, setQuery] = useState("");

const filtered = products.filter(p =>
  p.name.toLowerCase().includes(query.toLowerCase())
);
```

#### Step 3: Sort

```plaintext
// Add dropdown to sort filtered products by name (A-Z, Z-A)
```

```javascript
const [sortOrder, setSortOrder] = useState("asc");

const sorted = [...filtered].sort((a, b) => {
  return sortOrder === "asc"
    ? a.name.localeCompare(b.name)
    : b.name.localeCompare(a.name);
});
```

#### Step 4: Pagination

```plaintext
// Add pagination: 10 items per page, with next/prev buttons
```

```javascript
const [page, setPage] = useState(1);
const itemsPerPage = 10;
const paginated = sorted.slice((page - 1) * itemsPerPage, page * itemsPerPage);
```

### Why this works:

* Smaller prompts are easier for the model to handle
    
* Easier for me to review and test each change
    
* Reduces the chance of logic errors or inconsistent code
    

This is how you would break it into Jira tickets. Prompting works the same way.

## 4\. Use Behavioral Examples and Edge Cases

One of the most underrated prompt patterns is giving examples. Adding example inputs and outputs turns your prompt into a contract.

### ❌ Bad Prompt

```plaintext
Format this number into currency
```

### ✅ Prompt (Use TDD-Like Prompts)

```plaintext
Create a formatPrice(amount) function:
Input: 12.5 -> Output: "$12.50"
Input: 5 -> Output: "$5.00"
```

### ❌ Bad Prompt

```plaintext
Add a search bar
```

### ✅ With Edge Case:

```plaintext
Add a search input that filters products by name.
Case-insensitive. If query is "mob", it should match "Mobile", "MobX", etc.
If no matches, show "No results found".
```

Now the AI:

* Uses `toLowerCase()` for comparison
    
* Adds empty-state UI
    
* Handles common edge cases automatically
    

### **Why This Works:**

AI tools tend to *overlook* edge behavior unless explicitly prompted. Guardrails matter.

## 5\. Use Roles to Shift Quality

Prompt the AI to take on a role. You will often get a **shift in tone, architecture, and quality**.

```plaintext
Act like a senior React developer. Review this component for potential bugs or anti-patterns.
```

Or

```plaintext
You're a mentor explaining this useEffect logic to a junior dev. Add comments line-by-line.
```

This usually makes the AI:

* Explain itself better
    
* Write clearer code
    
* Catch things it otherwise skips
    

### Another Favourite:

```plaintext
You are a Tailwind expert. Rewrite this JSX with clean, utility-first styling and responsive behavior.
```

It uses `flex`, `gap`, `max-w`, `hover:` and other best practices not inline styles or CSS classes.

## Takeaway: Prompting = Product Thinking

[![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748633407722/fc133b8d-7c36-4042-9075-cd27246a6dd3.png align="center")](https://x.com/gregisenberg/status/1928230473228058860)

At its core, writing great prompts is no different from writing great specs or tickets:

* Be clear
    
* Define success
    
* Think in steps
    
* Handle edge cases
    
* Communicate like a teammate
    

AI isn’t here to replace good engineers, it amplifies great ones. Treat your AI assistant like a sharp new hire: fast, eager but needing direction.

The clearer you are, the better the code gets.
