AI & data

Effective prompting for programmers: a practical guide

David Morales VegaDecember 15, 202510 min read

Originally published on Bemorex Learn, our learning platform. · Leer en español

Why does prompting matter for developers?

The difference between a mediocre prompt and an excellent one can be the difference between code that barely works and production-ready code. As developers, we have an advantage: we think in a structured way and can apply that skill to prompting.

This article will teach you specific prompting techniques optimized for programming tasks.

Fundamental principles

1. Be specific with context

Language models cannot read your mind. The more context you provide, the better the result.

Weak prompt:

Create a login form

Strong prompt:

Create an Angular standalone login component with reactive forms. It should have email and password fields with validations (valid email, password minimum 8 characters). Use signals for loading state. Implement OnPush change detection. The form should display inline error messages below each field.

2. Define the constraints

Specifying what you DON'T want is as important as specifying what you do want.

Requirements:
- Strict TypeScript, no 'any'
- No external dependencies
- Compatible with Node.js 20+
- Complete error handling

Constraints:
- DO NOT use classes, only functions
- DO NOT use callbacks, only async/await
- DO NOT use console.log in production

3. Provide examples (Few-shot)

Showing the pattern you expect is more effective than describing the pattern.

Advanced techniques

Chain of Thought

Ask the model to reason step by step before generating code:

I need a function that determines if a string is a palindrome.

Before writing the code:
1. Define what a palindrome is
2. Consider edge cases (spaces, uppercase, special characters)
3. Evaluate different approaches and their complexity
4. Choose the best approach

Then implement the function in TypeScript.

This technique is especially useful for algorithmic problems and architecture decisions.

Role prompting

Assigning a specific role to the model significantly improves quality:

Act as a senior software engineer with 10 years of experience
in Angular and TypeScript. Your priority is maintainable code,
with strict types and tests. You prefer composition over inheritance
and pure functions over side effects.

Incremental prompting (Iterative)

For complex tasks, build the solution in steps:

  1. Step 1: Define the interface/types
  2. Step 2: Implement the core logic
  3. Step 3: Add error handling
  4. Step 4: Add tests
  5. Step 5: Optimize and refactor

Prompt template for code review

Review the following code considering:

1. **Bugs**: Logic errors or potential runtime errors
2. **Security**: Vulnerabilities (XSS, injection, etc.)
3. **Performance**: Expensive or unnecessary operations
4. **Types**: Correct use of the TypeScript type system
5. **Readability**: Names, structure, comments

Response format:
- Severity: CRITICAL | HIGH | MEDIUM | LOW
- Affected line(s)
- Problem description
- Suggested fix with code

[Paste your code here]

Prompts for common development tasks

Generate TypeScript interfaces

From this API JSON response:
[paste JSON]

Generate TypeScript interfaces that:
- Use strict types (no any)
- Handle optional fields correctly
- Include JSDoc with a description for each field
- Use descriptive PascalCase names

Refactor legacy code

Refactor this Angular code from the old version to modern:

Requirements:
- Migrate from NgModules to standalone components
- Migrate from constructor injection to inject()
- Migrate from decorators (@Input/@Output) to input()/output()
- Migrate from BehaviorSubject to signals
- Migrate from *ngIf/*ngFor to @if/@for

Maintain the same functionality. Explain each change.

[Paste code]

Write documentation

Generate technical documentation for this function/class:

Include:
1. General description (1-2 sentences)
2. Parameters with types and description
3. Return value
4. Basic usage example
5. Example with edge cases
6. Possible throws/errors

Format: TSDoc compatible

[Paste code]

Anti-patterns: what NOT to do

1. Vague prompts

Avoid: "Make a CRUD". It doesn't specify the technology, structure, validations, or error handling.

2. Asking for everything at once

A prompt with 50 requirements will produce mediocre results. Break it into steps.

3. Not validating the output

Always review and test generated code. Models can generate code that looks correct but has subtle bugs.

4. Copying without understanding

If you don't understand the generated code, don't use it. Ask for explanations.

Building a system prompt for your team

A well-designed system prompt can standardize the quality of generated code for your entire team.

Key elements

  • Tech stack: Specific versions of frameworks and libraries
  • Code conventions: Naming, file structure, patterns
  • Constraints: What should NOT be used
  • Response format: Expected output structure

Conclusion

Effective prompting for programmers comes down to three things: clear context, explicit constraints, and concrete examples. Invest time in building good prompts and reusable templates for your team.

AI is only as good as the instructions you give it. A developer who masters prompting multiplies their productivity significantly.

Code examples

TypeScript

// System prompt for a coding assistant
const systemPrompt = `You are an expert TypeScript and Angular assistant.

Rules:
1. Use strict typing, never use 'any'
2. Prefer signals over BehaviorSubject
3. Use standalone components
4. Implement OnPush change detection
5. Follow the single responsibility principle

Response format:
- First, briefly explain the approach
- Then show the code
- Finally, list important considerations`;

const response = await fetch('https://api.anthropic.com/v1/messages', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': process.env.ANTHROPIC_API_KEY ?? '',
    'anthropic-version': '2023-06-01'
  },
  body: JSON.stringify({
    model: 'claude-sonnet-4-20250514',
    max_tokens: 2048,
    system: systemPrompt,
    messages: [{
      role: 'user',
      content: 'Create an authentication service with Google OAuth'
    }]
  })
});

Markdown

# Few-shot prompting to generate tests

Generate unit tests following this pattern:

## Example 1:
Function: `function add(a: number, b: number): number`
Test:
```typescript
describe('add', () => {
  it('should add two positive numbers', () => {
    expect(add(2, 3)).toBe(5);
  });
  it('should handle negative numbers', () => {
    expect(add(-1, 1)).toBe(0);
  });
  it('should handle zero', () => {
    expect(add(0, 5)).toBe(5);
  });
});
```

## Now generate tests for:
Function: `function divide(a: number, b: number): number`

Keep reading

Want to build something like this?

Tell us what you need: we look at it together and propose a way forward in writing, in English or Spanish.

[email protected]