Skip to content

Code Review Best Practices Guide

DodaTech Updated 2026-06-24 8 min read

In this tutorial, you'll learn about Code Review Best Practices Guide. We cover key concepts, practical examples, and best practices.

Code review is the systematic examination of code changes by peers to catch bugs, improve quality, share knowledge, and enforce team standards before merging.

In this tutorial, you'll learn code review best practices — how to write reviewable code, give constructive feedback, use automated review tools, and establish team review workflows. Effective code reviews catch 60-80% of defects before they reach production, spread domain knowledge across the team, and create a culture of collective code ownership. By the end, you'll have a complete review checklist and workflow for your team.

Real-world use: DodaTech enforces code review on every pull request across Doda Browser, DodaZIP, and Durga Antivirus Pro. All repositories require at least one approval before merging, with critical security changes requiring two.

flowchart TD
  A[Developer pushes branch] --> B[Create Pull Request]
  B --> C[Automated Checks]
  C --> D[Lint / Test / Build]
  D --> E{All Pass?}
  E -->|No| F[Fix and push]
  F --> C
  E -->|Yes| G[Assign Reviewers]
  G --> H[Code Review]
  H --> I[Comments / Suggestions]
  I --> J{Approved?}
  J -->|No| K[Address feedback]
  K --> H
  J -->|Yes| L[Merge PR]
  L --> M[Delete branch]
  L --> N[Deploy]

What Makes a Good Code Review

Good reviews focus on correctness, design, maintainability, and security — not personal preference.

# Code Review Checklist

## Correctness
- [ ] Does the code do what it's supposed to do?
- [ ] Are edge cases handled (empty states, errors, timeouts)?
- [ ] Are there sufficient tests for the change?

## Design
- [ ] Does the code follow the project's architecture?
- [ ] Are functions and classes appropriately sized?
- [ ] Is the API intuitive and consistent?

## Maintainability
- [ ] Is the code readable without comments?
- [ ] Are variable and function names descriptive?
- [ ] Is there unnecessary complexity?

## Security
- [ ] Are user inputs validated and sanitized?
- [ ] Are secrets and credentials never hardcoded?
- [ ] Are authentication/authorization checks in place?

## Performance
- [ ] Are there unnecessary database queries or API calls?
- [ ] Are large data sets handled efficiently?
- [ ] Are there obvious memory leaks?

Writing Reviewable Code

Make the reviewer's job easier by keeping changes focused and well-structured.

# Bad: many unrelated changes in one commit
git log --oneline
# 7f3e2a1 "Fix bugs and update docs and refactor auth"

# Good: each commit has a single concern
git log --oneline
# a1b2c3d "Refactor auth middleware to use JWT"
# d4e5f6g "Update README with setup instructions"
# g7h8i9j "Fix: handle null callback in login handler"

PR title conventions that speed up reviews:

# Good PR titles (clear what and why)
feat(auth): add OAuth2 login with Google and GitHub
fix(dashboard): correct chart rendering on Safari
refactor(scanner): extract file analysis into separate module
docs: update API reference for v3.2 endpoints

# Bad PR titles (vague)
"Fix stuff"
"Update code"
"Changes"
"WIP"

Giving Constructive Feedback

The tone and structure of review comments determine whether they help or hurt team culture.

// ❌ Dismissive comment
// "This is wrong. Rewrite it."

// ✅ Constructive, specific comment
// "This function mutates the input array, which could cause
// unexpected side effects for callers. Consider returning
// a new array instead using .map() or spreading."



// ❌ Opinion without justification
// "Don't use forEach, use for...of instead."

// ✅ Opinion with reasoning
// "Using for...of here would let us `await` inside the loop
// and `break` early if we find the target. forEach can't
// do either. But if you're not awaiting or breaking,
// forEach is fine — this is optional."



// ❌ Nitpick without value
// "Rename `x` to `variableThatHoldsTheUserData`"

// ✅ Meaningful suggestion
// "Could we use a more specific name than `data`? Since this
// holds the parsed scan results, something like `scanResults`
// or `threatList` would make the intent clearer."

Automated Review Tools

Complement human review with automated tools that catch common issues.

# .github/workflows/review-checks.yml
name: Pre-Review Checks
on: [pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run lint
      - run: npm run typecheck

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test -- --coverage

  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Secret scanning
        uses: trufflesecurity/trufflehog@v3
        with:
          extra_args: --results=verified,unknown

Configure branch protection to require passing checks before review:

# GitHub CLI: set up branch protection
gh api repos/:owner/:repo/branches/main/protection \
  --method PUT \
  --field required_status_checks.contexts='["lint","test","security"]' \
  --field required_pull_request_reviews.required_approving_review_count=1 \
  --field enforce_admins=true

Review Workflows

Choose the workflow that matches your team's size and risk tolerance.

## Async Review (most common)
1. Developer creates PR
2. CI runs automated checks
3. Reviewer reviews asynchronously
4. Developer addresses feedback
5. Reviewer approves
6. PR is merged

Best for: Distributed teams, most changes

## Synchronous (pair review)
1. Developer and reviewer sit together (or screen share)
2. Walk through the code line by line
3. Discuss and fix issues immediately
4. PR approved and merged in one session

Best for: Complex changes, new team members, security-critical code

## Maintainer model
1. Contributors submit PRs
2. Maintainers review and merge
3. Contributors don't have merge access

Best for: Open source projects

Security-Focused Review

For security-critical changes, add extra review steps.

// Review: are we logging sensitive data?
function handleLogin(req, res) {
  const { username, password } = req.body;

  // RED FLAG: logging passwords
  console.log('Login attempt:', { username, password }); // ❌

  // OK: logging only non-sensitive metadata
  console.log('Login attempt:', { username, ip: req.ip }); // ✅
}

// Review: is input properly sanitized?
function queryDatabase(userInput) {
  // RED FLAG: SQL injection possible
  const query = `SELECT * FROM users WHERE name = '${userInput}'`; // ❌

  // OK: parameterized query
  const query = 'SELECT * FROM users WHERE name = $1'; // ✅
  return db.query(query, [userInput]);
}

// Review: is there proper access control?
function deleteUser(req, res) {
  const { userId } = req.params;

  // RED FLAG: no authorization check
  db.query('DELETE FROM users WHERE id = $1', [userId]); // ❌

  // OK: verify the caller has permission
  if (req.user.role !== 'admin') { // ✅
    return res.status(403).json({ error: 'Unauthorized' });
  }
  db.query('DELETE FROM users WHERE id = $1', [userId]);
}

Common Errors

  1. Reviewing too late — A 500-line PR arriving at 5 PM on Friday gets rushed. Keep PRs under 200 lines and schedule reviews during productive hours.
  2. Focusing only on style — Style is the least important aspect (and automated). Focus on correctness, security, and design.
  3. Rubber-stamping — Approving without reviewing because "it's just a small change" or "I trust the author." Small changes can have big security implications.
  4. Over-nitting — Requesting changes for trivial preferences (variable naming, formatting) when automated tools should handle it. Use a linter with rules the team agreed on.
  5. Not reviewing tests — Reviewing implementation code but ignoring tests misses the point. Check test quality: do they test the right cases? Are they readable?
  6. Blocking reviews — Taking more than 24 hours to review blocks team velocity. Establish SLAs: respond within 4 hours on workdays.

Practice Questions

What is the ideal size for a pull request?

Under 200 lines of changed code. Smaller PRs get faster, more thorough reviews. Break large features into multiple PRs using feature flags or incremental delivery. Research shows review effectiveness drops significantly beyond 400 lines.

How do you handle disagreement in code review?

Focus on objective criteria: the project's style guide, performance benchmarks, security requirements. If it's a design preference, discuss options and let the author decide. Use a decision-making framework: "Does this change make the code better or worse?" not "Is this how I would write it?"

What should be automated in code review?

Linting, formatting, type checking, test coverage, security scanning (secret detection, dependency vulnerabilities), and bundle size checks. Automate everything that doesn't require human judgment — this lets human reviewers focus on design, correctness, and security.

How do you review tests effectively?

Check: does the test actually test the code change? Are there meaningful assertions? Are edge cases covered? Are there tests for negative paths (errors, empty states)? Review test quality separately from implementation quality.

What is the reviewer's responsibility in a security-sensitive PR?

Verify: input validation on all user-facing data, proper authentication checks on every endpoint, no hardcoded secrets, parameterized database queries, proper authorization (not just authentication), and safe handling of user-controlled file paths

Challenge

Create a complete code review workflow for a new team. Define: PR size limits (max 300 lines), review SLA (response within 4 hours), required checks (lint, test, security scan), approval requirements (1 for most, 2 for security), and merge strategy (squash merge). Write a CODEOWNERS file that auto-assigns reviewers based on changed files.

Real-World Task

Implement the code review workflow for Durga Antivirus Pro's detection engine team. Set up branch protection rules requiring passing CI checks and one approval. Configure automated security scanning on every PR (secret detection, dependency vulnerabilities, SAST). Create a review checklist specific to detection engine changes (signature format validation, false positive testing, performance benchmarks). Establish a review rotation schedule so no one is the only reviewer for critical changes.


Previous: Pull Request Guide | Related: GitHub Issues & PRs | Related: Git for Teams

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro