Code Generation Prompt Templates

AI prompt templates for generating code. Get working implementations for various programming tasks.

Overview

AI-generated code is only as good as the prompt that describes it. Vague requests get generic code; specific prompts get production-ready implementations. These prompts help you communicate requirements precisely, including edge cases, error handling, and coding standards, so you get code you can actually use instead of code you have to rewrite.

Best Practices

1

Specify the exact technology stack (language version, frameworks, libraries) for compatible code

2

Include input/output examples to clarify expected behavior better than descriptions alone

3

Mention error handling requirements explicitly, otherwise you'll get happy-path-only code

4

Describe your coding style or point to existing code to match your codebase conventions

5

Ask for edge cases to be handled and specify which ones matter for your use case

Prompt Templates

1. Function Implementation

Write a function with these specifications:

**Function name:** [NAME]
**Purpose:** [WHAT IT DOES]
**Language:** [LANGUAGE AND VERSION]

**Inputs:**
- [PARAM 1]: [TYPE] - [DESCRIPTION]
- [PARAM 2]: [TYPE] - [DESCRIPTION]

**Output:** [RETURN TYPE] - [DESCRIPTION]

**Examples:**
```
Input: [EXAMPLE INPUT]
Output: [EXPECTED OUTPUT]

Input: [ANOTHER EXAMPLE]
Output: [EXPECTED OUTPUT]
```

**Requirements:**
- [REQUIREMENT 1 - e.g. must handle empty input]
- [REQUIREMENT 2 - e.g. must be O(n) time complexity]

**Error handling:**
- [WHAT TO DO ON INVALID INPUT]

**Style:** [ANY CONVENTIONS - e.g. use early returns, prefer const]
Function: calculateDiscount
Purpose: Apply tiered discount based on order total
Language: TypeScript 5
Inputs: total (number), customerTier ('bronze'|'silver'|'gold')
Output: number - discounted total
Examples: (100, 'bronze') → 95, (100, 'gold') → 80
Requirements: Discounts are 5%/10%/20% for bronze/silver/gold, minimum total is $0
Error handling: Throw on negative total, return original total for unknown tier
```typescript
type CustomerTier = 'bronze' | 'silver' | 'gold';

const DISCOUNT_RATES: Record<CustomerTier, number> = {
 bronze: 0.05,
 silver: 0.10,
 gold: 0.20,
};

/**
 * Applies tiered discount to order total based on customer membership.
 * @param total - Order total before discount (must be non-negative)
 * @param customerTier - Customer's membership tier
 * @returns Discounted total, minimum $0
 * @throws {RangeError} If total is negative
 */
export function calculateDiscount(
 total: number,
 customerTier: CustomerTier | string
): number {
 if (total < 0) {
 throw new RangeError(`Total cannot be negative: ${total}`);
 }

 const discountRate = DISCOUNT_RATES[customerTier as CustomerTier] ?? 0;
 const discountedTotal = total * (1 - discountRate);
 
 return Math.max(0, discountedTotal);
}
```

**Implementation notes:**
- Used `Record` type for discount rates, easy to add new tiers
- Unknown tier falls back to 0% discount (returns original total)
- `Math.max(0...)` ensures we never return negative
- JSDoc comments for IDE support

When you need a specific function implemented with clear requirements

  • Input/output examples are worth 100 words of description, always include them
  • Mention what should NOT happen (constraints) as well as what should happen

2. Class/Module Generator

Create a class/module with these specifications:

**Name:** [CLASS/MODULE NAME]
**Purpose:** [WHAT IT DOES]
**Language:** [LANGUAGE]
**Framework:** [IF APPLICABLE]

**Properties/State:**
- [PROPERTY 1]: [TYPE] - [DESCRIPTION]
- [PROPERTY 2]: [TYPE] - [DESCRIPTION]

**Methods:**
1. [METHOD NAME]([PARAMS]) → [RETURN TYPE]: [WHAT IT DOES]
2. [METHOD NAME]([PARAMS]) → [RETURN TYPE]: [WHAT IT DOES]

**Behavior:**
- [BEHAVIOR 1 - e.g. thread-safe]
- [BEHAVIOR 2 - e.g. lazy initialization]

**Dependencies:** [WHAT IT NEEDS]

**Usage example:**
```
[HOW IT SHOULD BE USED]
```
Name: RateLimiter
Purpose: Limit API requests per user using sliding window
Language: Python 3.11
Properties: max_requests (int), window_seconds (int)
Methods: is_allowed(user_id) → bool, get_remaining(user_id) → int, reset(user_id)
Behavior: Thread-safe, auto-cleanup of old entries
Dependencies: None (standard library only)
Usage: limiter = RateLimiter(100, 60); if limiter.is_allowed('user123'): process_request()
```python
import threading
import time
from collections import defaultdict
from dataclasses import dataclass, field


@dataclass
class RateLimiter:
 """Sliding window rate limiter with automatic cleanup.
 
 Thread-safe rate limiter that tracks requests per user within a
 configurable time window.
 
 Example:
 limiter = RateLimiter(max_requests=100, window_seconds=60)
 if limiter.is_allowed('user123'):
 process_request()
 else:
 raise RateLimitExceeded(limiter.get_remaining('user123'))
 """
 
 max_requests: int
 window_seconds: int
 _requests: dict = field(default_factory=lambda: defaultdict(list))
 _lock: threading.Lock = field(default_factory=threading.Lock)
 
 def is_allowed(self, user_id: str) -> bool:
 """Check if request is allowed and record it if so."""
 with self._lock:
 self._cleanup(user_id)
 
 if len(self._requests[user_id]) >= self.max_requests:
 return False
 
 self._requests[user_id].append(time.time())
 return True
 
 def get_remaining(self, user_id: str) -> int:
 """Get number of requests remaining in current window."""
 with self._lock:
 self._cleanup(user_id)
 return max(0, self.max_requests - len(self._requests[user_id]))
 
 def reset(self, user_id: str) -> None:
 """Clear all tracked requests for a user."""
 with self._lock:
 self._requests.pop(user_id, None)
 
 def _cleanup(self, user_id: str) -> None:
 """Remove requests outside the current window."""
 cutoff = time.time() - self.window_seconds
 self._requests[user_id] = [
 ts for ts in self._requests[user_id] if ts > cutoff
 ]
```

**Implementation notes:**
- Uses `threading.Lock` for thread safety
- Sliding window via timestamp list (accurate but uses more memory than fixed window)
- Cleanup on every access keeps memory bounded
- `defaultdict` avoids key existence checks

When you need a complete class or module with multiple methods and specific behaviors

  • Describe the behaviors (thread-safe, immutable, lazy) not just the methods
  • Include a usage example in your prompt, it clarifies the intended API

3. API Endpoint Implementation

Implement this API endpoint:

**Framework:** [EXPRESS / FASTAPI / FLASK / etc.]
**Endpoint:** [METHOD] [PATH]
**Purpose:** [WHAT IT DOES]

**Request:**
- Headers: [REQUIRED HEADERS]
- Body: [REQUEST BODY SCHEMA]
- Params: [URL/QUERY PARAMS]

**Response:**
- Success: [STATUS CODE] - [RESPONSE BODY]
- Errors: [ERROR SCENARIOS AND RESPONSES]

**Business logic:**
- [VALIDATION RULES]
- [PROCESSING STEPS]
- [SIDE EFFECTS - database, email, etc.]

**Include:**
- Input validation
- Error handling
- [AUTHENTICATION IF REQUIRED]
- [ANY MIDDLEWARE]
Framework: Express.js with TypeScript
Endpoint: POST /api/v1/orders
Purpose: Create a new order
Request body: { items: [{productId, quantity}], shippingAddress: {...} }
Response: 201 with order object, 400 for validation errors, 409 if insufficient stock
Business logic: Validate stock, calculate total, create order, send confirmation email
Include: JWT auth middleware, request validation with Zod
```typescript
import { Router, Request, Response, NextFunction } from 'express';
import { z } from 'zod';
import { authMiddleware } from '../middleware/auth';
import { OrderService } from '../services/OrderService';
import { InsufficientStockError } from '../errors';

const router = Router();

// Request validation schema
const CreateOrderSchema = z.object({
 items: z.array(z.object({
 productId: z.string().uuid(),
 quantity: z.number().int().positive(),
 })).min(1, 'Order must have at least one item'),
 shippingAddress: z.object({
 street: z.string().min(1),
 city: z.string().min(1),
 state: z.string().length(2),
 zipCode: z.string().regex(/^\d{5}(-\d{4})?$/),
 }),
});

type CreateOrderRequest = z.infer<typeof CreateOrderSchema>;

/**
 * POST /api/v1/orders
 * Create a new order for the authenticated user
 */
router.post(
 '/api/v1/orders',
 authMiddleware,
 async (req: Request, res: Response, next: NextFunction) => {
 try {
 // Validate request body
 const validationResult = CreateOrderSchema.safeParse(req.body);
 if (!validationResult.success) {
 return res.status(400).json({
 error: 'VALIDATION_ERROR',
 details: validationResult.error.errors,
 });
 }

 const { items, shippingAddress } = validationResult.data;
 const userId = req.user!.id; // Set by authMiddleware

 // Create order (validates stock, calculates total, sends email)
 const orderService = new OrderService();
 const order = await orderService.createOrder({
 userId,
 items,
 shippingAddress,
 });

 return res.status(201).json({
 id: order.id,
 status: order.status,
 items: order.items,
 total: order.total,
 shippingAddress: order.shippingAddress,
 createdAt: order.createdAt,
 });
 } catch (error) {
 if (error instanceof InsufficientStockError) {
 return res.status(409).json({
 error: 'INSUFFICIENT_STOCK',
 message: error.message,
 productId: error.productId,
 available: error.availableQuantity,
 });
 }
 next(error); // Pass to error handler
 }
 }
);

export default router;
```

**Implementation notes:**
- Zod validation with detailed error messages
- Typed request body from schema inference
- Business logic delegated to OrderService (keeps controller thin)
- Specific error handling for known error types
- Unknown errors passed to global error handler

When implementing REST API endpoints with proper validation, error handling, and business logic

  • Specify your validation library preference, Zod, Joi, class-validator all have different patterns
  • Include error scenarios in the prompt to get proper error handling, not just happy path

4. Data Transformation Utility

Write a utility function to transform data:

**Purpose:** [WHAT TRANSFORMATION IT PERFORMS]
**Language:** [LANGUAGE]

**Input format:**
```[LANGUAGE]
[DESCRIBE OR SHOW INPUT STRUCTURE]
```

**Output format:**
```[LANGUAGE]
[DESCRIBE OR SHOW OUTPUT STRUCTURE]
```

**Transformation rules:**
- [RULE 1 - e.g. flatten nested arrays]
- [RULE 2 - e.g. rename field 'old' to 'new']
- [RULE 3 - e.g. filter out inactive items]

**Edge cases to handle:**
- [EDGE CASE 1 - e.g. missing fields]
- [EDGE CASE 2 - e.g. null values]

**Example:**
```
Input: [CONCRETE EXAMPLE]
Output: [EXPECTED OUTPUT]
```
Purpose: Transform API response to frontend format
Language: TypeScript
Input: { user: { first_name, last_name, email_address, created_at }, orders: [...] }
Output: { name: string, email: string, memberSince: Date, orderCount: number }
Rules: Combine names, rename email_address to email, convert created_at to Date, count orders
Edge cases: Missing orders (treat as empty), null names (use 'Unknown')
```typescript
interface ApiResponse {
 user: {
 first_name: string | null;
 last_name: string | null;
 email_address: string;
 created_at: string;
 };
 orders?: Array<{ id: string }>;
}

interface UserDisplay {
 name: string;
 email: string;
 memberSince: Date;
 orderCount: number;
}

/**
 * Transforms API user response to frontend display format.
 * Handles missing/null values gracefully.
 */
export function transformUserResponse(response: ApiResponse): UserDisplay {
 const { user, orders } = response;
 
 // Combine names, handling nulls
 const firstName = user.first_name?.trim() || '';
 const lastName = user.last_name?.trim() || '';
 const name = [firstName, lastName].filter(Boolean).join(' ') || 'Unknown';
 
 return {
 name,
 email: user.email_address,
 memberSince: new Date(user.created_at),
 orderCount: orders?.length ?? 0,
 };
}

// Usage examples:
// transformUserResponse({ user: { first_name: 'Jane', last_name: 'Doe', email_address: 'jane@example.com', created_at: '2024-01-15T10:30:00Z' }, orders: [{id: '1'}, {id: '2'}] })
// → { name: 'Jane Doe', email: 'jane@example.com', memberSince: Date, orderCount: 2 }

// transformUserResponse({ user: { first_name: null, last_name: null, email_address: 'anon@example.com', created_at: '2024-01-15T10:30:00Z' } })
// → { name: 'Unknown', email: 'anon@example.com', memberSince: Date, orderCount: 0 }
```

**Why this approach:**
- Explicit types for both input and output shapes
- Defensive handling of null/undefined with sensible defaults
- `filter(Boolean)` cleanly removes empty strings from name array
- Optional chaining + nullish coalescing for concise null handling

When you need to transform data between different formats, API responses, database records, file formats

  • Always provide a concrete input/output example, it catches misunderstandings in the description
  • List edge cases explicitly, data transformation bugs usually come from unexpected values

Common Mistakes to Avoid

Not specifying the exact language version or framework, getting incompatible syntax or deprecated APIs

Describing requirements in prose instead of showing examples, leading to misinterpretation

Forgetting to mention error handling, getting code that only handles the happy path

Frequently Asked Questions

AI-generated code is only as good as the prompt that describes it. Vague requests get generic code; specific prompts get production-ready implementations. These prompts help you communicate requirements precisely, including edge cases, error handling, and coding standards, so you get code you can actually use instead of code you have to rewrite.

Related Templates

Have your own prompt to optimize?