Reviewing code as human

Published: (March 7, 2026 at 06:07 AM EST)
4 min read
Source: Dev.to

Source: Dev.to

One of my strengths is spotting issues in others’ code 😜. Below is a checklist I use when reviewing a PR. While AI tools like Copilot can help, they still miss nuances that require human judgment.

Reusability

Repeated logic

  • Can the logic be extracted into a reusable component or function?
  • Is the extracted code properly tested so it can be reused without rewriting or retesting?
  • Updating the logic in one place should automatically propagate everywhere, reducing bugs caused by inconsistent implementations.

Hard‑coded, repeated values

  • Store such values as constants in a shared file.
  • Using constants reduces typos and makes future changes a single‑point edit.
  • Modern IDEs autocomplete imported constants, further minimizing errors.

Testability

  • Did any previously passing tests start failing or need changes?
    • Failing tests may indicate an unintended modification, typo, or side‑effect.
    • Verify the implementation first; don’t just “fix the test.”
    • Review the diff carefully for missing braces, typos, or subtle logic changes.

Readability / Understandability

Naming

  • Names should describe what the component, file, variable, or function does.
    • Example: a boolean that indicates whether a button should be shown could be named isButtonVisible.
    • Clear names reduce the need for extra comments and help both humans and AI understand the code.

Complex logic

  • Too many if/else statements?
    • Consider a switch statement or refactor into smaller helper functions.

Function arguments

  • Too many arguments?
    • Pass a single object with named properties instead of a long positional list.
    • This avoids ordering mistakes and makes optional arguments clearer.

Comments & business logic

  • If the code is hard to follow, add comments that explain the underlying business rules.
  • Important logic should also be covered by unit and end‑to‑end tests.

Security

Even with static analysis, some insecure patterns can slip through.

  • Never trust user input – sanitize raw inputs before sending them to the server or rendering them in the browser (prevents XSS).
  • Protect PII – mask or encrypt personally identifiable information before sending it to third‑party services.
  • Avoid leaking secrets – ensure API tokens, secrets, and .env files are not committed. Rotate any exposed credentials immediately.

Error Handling

  • Handle expected errors – wrap network requests (e.g., fetch) in try/catch blocks.
  • Avoid unintended mutation – clone objects before modifying them, or use getters that return read‑only values.
  • User‑facing error messages – don’t expose stack traces, server details, or other sensitive information that could aid an attacker.

Type Safety

  • Ensure all data, especially API responses, are typed correctly (e.g., using TypeScript interfaces or types).
  • Well‑defined types catch mismatches early and make the codebase easier to maintain.

Summary

Balancing thoroughness with practicality is key. Human judgment lets us decide what’s “good enough” and what needs deeper scrutiny—something AI alone can’t fully replicate. Use this checklist as a living document; adapt it as your team and codebase evolve.

Avoiding Mistakes

Here’s less chance of mistakes. For example, you might check whether a key has a particular name before converting its value to uppercase. If you type in the wrong key name, the code will not work as expected.

Another issue is when a field is optional; if you don’t know it’s optional, you might skip checking whether it’s defined, causing runtime errors when it’s missing. Having interfaces defined allows your IDE to help you identify the exact key names and avoid mistakes caused by wrong assumptions.

Optimization

I also look for places where lines of code can be optimized. Fewer lines of code often mean fewer opportunities for bugs.

  • In some cases, you can check if there’s already a utility function with similar logic that can be reused. Look for ways to adapt or slightly extend that utility function so it can support the new implementation.
  • Do you really need to assign intermediate variables where you could use object mapping or chaining directly? Extra variables can use more memory—often negligible on their own—but small changes like this can add up and improve performance over time.

I am sure there are more things I look for in a PR, but these are the top ones I can think of right now. What’s important is that you care about the product, your application’s users, yourself, and your teammates. If you care enough, you’ll notice most mistakes in the code and try to fix them. That’s what makes us special as human reviewers.

0 views
Back to Blog

Related posts

Read more »

Not All Friction Is the Same

Introduction Lately there are many posts celebrating the “death of friction,” praising how AI removes the friction of writing code and increases development ve...