Back to Blog
Developer ToolsDebuggingProductivityTutorial

How to Debug Anything -- A Systematic Guide for Developers

Published on April 6, 202612 min read

How to Debug Anything -- A Systematic Guide for Developers

Every developer knows the feeling. Something is broken. You have no idea why. You start changing random things, adding console.log everywhere, and hoping something clicks. Two hours later, you find a typo in a variable name.

Debugging is a skill, not a talent. Experienced developers are not better debuggers because they are smarter. They are better because they follow a process. This guide teaches you that process.


The Debugging Mindset

Before touching any code, internalize these principles:

1. The Bug Is Not Random

Computers are deterministic. If something broke, something changed. Your job is to find what changed. Common causes:

  • New code you or someone else pushed
  • A dependency update
  • An environment change (different OS, Node version, database state)
  • Different input data than what you tested with
  • A timing issue (race condition)

2. Reproduce First, Fix Second

You cannot debug what you cannot reproduce. If a user reports a bug, your first job is to make it happen on your machine. Only then can you investigate.

Questions to ask:

  • What exactly did the user do?
  • What browser/device/OS are they using?
  • Can you reproduce it with the same input data?
  • Does it happen every time or intermittently?

3. One Change at a Time

When testing a hypothesis, change ONE thing, then check if the behavior changed. If you change three things and the bug disappears, you do not know which change fixed it -- and you might have introduced a new problem.


The Debugging Process

Step 1: Define the Problem Precisely

"It is broken" is not a bug description. Get specific:

  • Bad: "The login page does not work."
  • Good: "Clicking the login button with valid credentials shows a 500 error. The network tab shows the POST to /api/auth returns 500. The server log shows: TypeError: Cannot read properties of undefined (reading 'email')"

The more precisely you define the problem, the faster you find the cause.

Step 2: Reproduce the Bug

Write down the exact steps to reproduce:

  1. 1Go to /login
  2. 2Enter email: test@example.com
  3. 3Enter password: password123
  4. 4Click "Sign In"
  5. 5Expected: redirect to dashboard
  6. 6Actual: 500 error displayed

If you cannot reproduce it, gather more information. Check logs, ask the user for screenshots, try different browsers.

Step 3: Isolate the Location

Narrow down WHERE the bug is happening. Use the process of elimination:

  • Frontend or backend? Check the network tab. If the API returns the correct data but the UI is wrong, it is a frontend bug. If the API returns wrong data, it is backend.
  • Which file? Add logging at the entry point of the function and the exit point. Is the input correct? Is the output correct?
  • Which line? Binary search through the function. Add a log in the middle. Is the data correct at that point? If yes, the bug is in the second half. If no, the first half. Repeat.

Step 4: Form a Hypothesis

Based on what you know, make a specific guess:

  • "The user object is null because the database query is returning no results."
  • "The CSS is overridden by a more specific selector on this page."
  • "The API key is missing in the production environment variables."

Step 5: Test Your Hypothesis

Design a test that proves or disproves your hypothesis:

  • Add a log statement right before the suspected line
  • Check the database directly
  • Inspect the environment variables on the server
  • Use the debugger to step through the code

Step 6: Fix and Verify

Once you find the cause, fix it. Then verify:

  • Does the original reproduction case work?
  • Do related features still work? (regression check)
  • Does it work in the environment where it was reported? (not just your machine)

Frontend Debugging

Console Methods You Should Be Using

Most developers only use console.log. There are better tools:

> console.log("simple value:", variable);

> console.table(arrayOfObjects); // displays data as a table

> console.group("API Call"); // groups related logs together

> console.log("URL:", url);

> console.log("Params:", params);

> console.groupEnd();

> console.time("render"); // start a timer

> // ... code to measure ...

> console.timeEnd("render"); // prints elapsed time

> console.trace("How did we get here?"); // prints the call stack

> console.assert(x > 0, "x should be positive", x); // only logs if assertion fails

Network Tab Debugging

The Network tab in DevTools tells you everything about HTTP requests:

  1. 1Open DevTools (F12 or Cmd+Option+I)
  2. 2Go to the Network tab
  3. 3Reproduce the issue
  4. 4Click on the failing request

Check:

  • Status code: 200 is success, 4xx is client error, 5xx is server error
  • Request headers: is the auth token being sent?
  • Request body: is the data formatted correctly?
  • Response body: what did the server actually return?
  • Timing: is the request slow, or did it time out?

DOM Debugging

When the UI looks wrong:

  1. 1Right-click the element and select "Inspect"
  2. 2Check the Styles panel -- is a style being overridden? (Look for crossed-out lines)
  3. 3Check the Computed panel -- what are the final computed values?
  4. 4Check the Layout panel -- for flexbox/grid debugging, this shows you the actual layout model

JavaScript Debugger

The debugger is more powerful than console.log:

  1. 1Open the Sources tab in DevTools
  2. 2Find your file (Cmd+P to search)
  3. 3Click on a line number to set a breakpoint
  4. 4Reproduce the bug -- execution pauses at the breakpoint

While paused:

  • Hover over variables to see their values
  • Use the Scope panel to see all local/closure/global variables
  • Use the Call Stack panel to see how you got here
  • Step Over (F10) to execute the current line and move to the next
  • Step Into (F11) to enter a function call
  • Step Out (Shift+F11) to finish the current function and return

React Debugging

Install the React DevTools browser extension:

  • Components tab: inspect component props, state, and hooks in real time
  • Profiler tab: identify which components re-render and why

Common React bugs:

  • Stale closures: a useEffect or callback captures an old value. Check your dependency arrays.
  • Infinite re-renders: a useEffect that updates state that is in its own dependency array.
  • Missing keys: list items without unique keys cause rendering glitches.

Backend Debugging

Reading Stack Traces

A stack trace tells you exactly where the error occurred and how the code got there. Read from top to bottom:

> TypeError: Cannot read properties of undefined (reading 'email')

> at getUserEmail (/app/src/auth.ts:42:18)

> at loginHandler (/app/src/routes/login.ts:15:22)

> at Layer.handle (/app/node_modules/express/lib/router/layer.js:95:5)

Translation:

  1. 1The error is TypeError: Cannot read properties of undefined (reading 'email')
  2. 2It happened in auth.ts at line 42 inside the function getUserEmail
  3. 3That function was called from login.ts at line 15 inside loginHandler

Go to auth.ts line 42. Something on that line is undefined when the code tries to access .email. Work backward: what is supposed to have the email property? Where does it come from? Why is it undefined?

Node.js Debugging

Use the built-in debugger:

> node --inspect server.js

Then open chrome://inspect in Chrome and click "inspect" on your Node process. You get the full Chrome DevTools debugger for your backend code.

Or use VS Code's built-in debugger:

  1. 1Go to the Run and Debug panel (Cmd+Shift+D)
  2. 2Click "create a launch.json file"
  3. 3Select Node.js
  4. 4Set breakpoints in your code
  5. 5Press F5 to start debugging

Python Debugging

Use the built-in pdb debugger:

> import pdb; pdb.set_trace() # add this line where you want to pause

Or use the newer breakpoint() function (Python 3.7+):

> breakpoint() # same thing, cleaner syntax

While paused:

  • n -- next line (step over)
  • s -- step into function
  • c -- continue execution
  • p variable -- print a variable
  • l -- show current code context
  • q -- quit debugger

Database Debugging

When data looks wrong:

  1. 1Check the query: log the actual SQL being executed, including parameter values
  2. 2Run the query directly: paste it into a database client and see what it returns
  3. 3Check the data: look at the actual rows in the table. Is the data what you expect?
  4. 4Check migrations: did a recent migration change the schema?
  5. 5Check connections: is the app connected to the right database? (staging vs production is a common mistake)

Common Bug Patterns

Recognizing patterns speeds up debugging dramatically:

Off-by-One Errors

The bug: a loop runs one too many or one too few times. An array index is out of bounds. A date calculation is off by one day.

Where to look: any code with array indices, loop boundaries, or date arithmetic. Check whether your boundaries are inclusive or exclusive.

Race Conditions

The bug: it works 90% of the time but randomly fails. The behavior depends on timing.

Where to look: any code where two operations can happen in parallel -- API calls, database writes, file access, state updates. Add logging with timestamps to see the order of operations.

Null/Undefined Reference Errors

The bug: "Cannot read properties of undefined."

Where to look: trace the variable backward. Where is it assigned? Is the assignment conditional? Could the data source (API, database, user input) return null? Add null checks or use optional chaining (?.) at the boundary.

Environment Differences

The bug: it works on your machine but not in production.

Where to look: environment variables, Node/Python version, database version, file system paths, timezone, available memory, network configuration.

Caching Issues

The bug: you changed the code but the old behavior persists.

Where to look: browser cache (hard refresh with Cmd+Shift+R), CDN cache, server-side cache (Redis, Memcached), build cache, DNS cache. When in doubt, clear everything and test again.


Debugging Tools Worth Installing

  • jq -- format and query JSON in the terminal
  • httpie or curl -- test APIs without a browser
  • ngrok -- expose your local server to the internet (useful for webhook debugging)
  • Postman -- GUI for API testing with saved collections
  • React DevTools -- browser extension for React debugging
  • Redux DevTools -- browser extension for Redux state debugging

When You Are Truly Stuck

  1. 1Take a break. Walk away for 15 minutes. Your subconscious keeps working on the problem.
  2. 2Explain it to someone. Rubber duck debugging works because articulating the problem forces you to think clearly. Explain what should happen, what actually happens, and what you have tried.
  3. 3Check the git log. When did it last work? What changed since then? Use git bisect to binary-search through commits.
  4. 4Read the source. If a library is behaving unexpectedly, read its source code. The answer is always in the code.
  5. 5Search with the exact error message. Copy the error message verbatim and search. Someone else has hit the same issue.
  6. 6Sleep on it. Seriously. Complex bugs often become obvious after rest.

The Cost of Not Debugging Systematically

Random debugging (changing things and hoping) has compounding costs:

  • You introduce new bugs while "fixing" the original one
  • You waste hours on wild goose chases
  • You do not learn the codebase because you never understand what went wrong
  • You lose confidence and start doubting your code even when it is correct

Systematic debugging takes discipline, but it is faster even for simple bugs. And for complex ones, it is the only approach that works.

For more developer guides and free tools, check out our blog and explore our developer tools.

Explore Our Free Tools & Games

Check out our curated collection of completely free browser games, tools, and extensions.

Browse Free Stuff

More Articles

Developer ToolsJSON

Stop Squinting at Messy JSON - Format It Instantly (Free Tool Inside)

Messy JSON is a productivity killer. Learn why formatting matters, common JSON pitfalls developers hit daily, and try our free browser-based JSON Formatter that works instantly with zero sign-ups.

7 min readRead More→
Browser GamesFree Games

Best Free Browser Games You Can Play Right Now in 2025

Discover the top free browser games of 2025 that require no downloads, no installs, and no sign-ups. From puzzle games to multiplayer adventures, these games run right in your browser.

8 min readRead More→
Developer ToolsFree Tools

Free Developer Tools Every Programmer Needs in Their Toolkit

A comprehensive guide to the best free developer tools available online. From JSON formatters to regex testers, these browser-based tools will supercharge your productivity.

10 min readRead More→
Chrome ExtensionsProductivity

10 Free Chrome Extensions That Will Boost Your Productivity

These free Chrome extensions will transform how you browse, work, and manage your time online. From tab management to dark mode, these extensions are must-haves.

7 min readRead More→