Claude Code Pull Request Review Skill Guide 2026

Written by Michael Lip · Solo founder of Zovo · $400K+ on Upwork · 100% JSS Join 50+ builders · More at zovo.one

The Workflow

Create a reusable Claude Code skill that reviews pull requests for code quality, security issues, performance concerns, and style guide compliance. The skill generates structured review comments that can be posted directly to GitHub PRs.

Expected time: 20-30 minutes to build the skill Prerequisites: Claude Code installed, GitHub CLI (gh) configured, repository with pull requests

Setup

1. Create the Skill Directory

mkdir -p .claude/skills/pr-review

2. Write the PR Review Skill

cat > .claude/skills/pr-review/SKILL.md << 'EOF'
---
name: pr-review
description: >
  Reviews pull requests for code quality, security, performance,
  and style guide compliance. Generates structured feedback.
  Triggers on "review PR", "check PR", "review pull request".
---

# Pull Request Review Skill

When reviewing a pull request:

## Process
1. Get the PR diff using `gh pr diff <number>`
2. Get PR metadata using `gh pr view <number>`
3. Analyze changes against the checklist below
4. Generate structured review comments

## Review Checklist

### Security
- No hardcoded secrets, API keys, or credentials
- No SQL injection vectors (raw string concatenation in queries)
- No unsafe deserialization
- Input validation present on all user-facing endpoints
- Authentication/authorization checks not bypassed

### Code Quality
- Functions under 50 lines
- No deeply nested conditionals (max 3 levels)
- Error handling present (no swallowed errors)
- No console.log or print statements left in
- Dead code removed (commented-out blocks)
- DRY: no copy-pasted logic blocks

### Performance
- No N+1 query patterns
- Database queries use appropriate indexes
- Large lists paginated, not loaded entirely
- No synchronous blocking in async contexts
- Memoization used for expensive computations

### Testing
- New code has corresponding tests
- Edge cases covered (null, empty, boundary values)
- No flaky test patterns (timers, race conditions)
- Mocks cleaned up properly

### Style
- Follows project CLAUDE.md conventions
- Consistent naming patterns
- Imports organized and no unused imports
- TypeScript: no `any` types

## Output Format
For each issue found, output:

[SEVERITY] file:line - description Suggestion: specific fix recommendation


Severity levels: CRITICAL, HIGH, MEDIUM, LOW, NIT
EOF

3. Verify the Skill Loads

claude --print "List available skills"
# Expected output:
# Should include "pr-review" in the list

Usage Example

Use the skill to review a pull request:

# Review PR #42
claude --print "Review PR 42 using the pr-review skill"

Here is what the skill produces in practice. Given a PR that adds a new API endpoint:

// The PR contains this new file: src/api/users/search.ts
import { Router } from 'express';
import { db } from '../../db';

const router = Router();

router.get('/search', async (req, res) => {
  const query = req.query.q;
  const results = await db.raw(`SELECT * FROM users WHERE name LIKE '%${query}%'`);
  console.log('Search results:', results);
  res.json(results);
});

export default router;

The skill generates this review:

## PR Review: #42 — Add user search endpoint

### Issues Found: 4

**[CRITICAL]** src/api/users/search.ts:8 - SQL injection vulnerability
The query parameter is concatenated directly into a SQL string without
sanitization. An attacker can inject arbitrary SQL.
Suggestion: Use parameterized queries:
```sql
SELECT * FROM users WHERE name LIKE ?
const results = await db.raw(
  'SELECT * FROM users WHERE name LIKE ?',
  [`%${query}%`]
);

[HIGH] src/api/users/search.ts:8 - No input validation The q query parameter is used without validation. It could be undefined, empty, or excessively long. Suggestion: Add validation with a max length:

const query = req.query.q;
if (!query || typeof query !== 'string' || query.length > 100) {
  return res.status(400).json({ error: 'Invalid search query' });
}

[MEDIUM] src/api/users/search.ts:9 - Console.log left in code Debug logging should not ship to production. Suggestion: Remove the console.log or replace with project logger:

import { logger } from '../../lib/logger';
logger.debug('Search executed', { query, resultCount: results.length });

[LOW] src/api/users/search.ts:8 - SELECT * is inefficient Fetching all columns is wasteful and may expose sensitive fields. Suggestion: Select only needed columns:

SELECT id, name, email, avatar_url FROM users WHERE name LIKE ?

Summary

Recommendation: REQUEST CHANGES


Automate reviews with a Git hook or GitHub Action:

```bash
# Post review comments to GitHub
cat > .github/workflows/claude-review.yml << 'WORKFLOW'
name: Claude PR Review
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Get PR diff
        run: gh pr diff ${{ github.event.number }} > /tmp/pr-diff.txt
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Run Claude review
        run: |
          claude --print "Review this diff for security, quality, and style issues. Output as GitHub review comments in JSON format: $(cat /tmp/pr-diff.txt)" > /tmp/review.json
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
WORKFLOW

Common Issues

Why This Matters

Automated PR reviews catch security vulnerabilities and code quality issues before human reviewers see the PR. This reduces review cycles from days to minutes for common issues.