BACK TO BLOGS
Node.jsDXProductivity

Small things I wish someone told me before I wasted hours debugging nothing

April 17, 2025 6 min read

You know that feeling when you've been staring at a bug for two hours and it turns out the server you "stopped" was never actually stopped? Yeah. This is that post.

These aren't framework tricks or DSA patterns. These are the embarrassingly simple things that'll make your day-to-day dev life actually bearable. The stuff nobody puts in tutorials because it's "too basic" — except it isn't, because everyone runs into it.

1. Your Node server is lying to you about the port

Vite is honest. When port 5173 is already taken, it tells you — "hey, something's already running here, want me to use 5174?" Clean, helpful, done.

Node doesn't do that. By default it either crashes with a wall of text you have to decode, or worse — it silently runs the old instance while you're testing the new one. You'll spend 30 minutes wondering why your changes aren't reflecting. They are reflecting — just on a zombie process you forgot about.

Add this when you start your server. Two lines:

JS
const server = app.listen(3000, () => {
  console.log("Server running on port 3000");
});

server.on("error", (err) => {
  if (err.code === "EADDRINUSE") {
    console.error("❌ Port 3000 is already in use. Kill it first.");
    process.exit(1);
  }
});

Now it yells at you immediately instead of pretending everything is fine. And if you want to actually find what process is squatting on your port:

netstat -ano | findstr :3000
# gives you a PID like 24496

# then in PowerShell:
Get-Process -Id 24496 | Format-List *
The PID you get from netstatis the process ID. Plug it into Task Manager or PowerShell and you'll see exactly what's holding the port. Usually it's a previous Node process that didn't exit cleanly.

2. Add one route that saves you every time

How many times have you hit an API, gotten nothing back, and spent ten minutes checking Postman, checking the controller, checking the route file — only to realize you had a typo in the URL?

Express doesn't tell you "that route doesn't exist." It just hangs. Or times out. Or gives you whatever the last middleware returned.

Put this at the very bottom of your app.js. After every other route:

JS
// ✅ This goes at the VERY END of app.js — after all your routes
app.use((req, res) => {
  res.status(404).json({ message: "Route not found" });
});

That's it. Now when you hit a wrong URL you immediately know — it's not your logic, it's not your controller, it's the route itself. Express reads top to bottom, so this only fires when nothing else matched.

Order matters here. If you put this before your actual routes, every request returns 404. It must be the last thing in the file.

3. Morgan — just add it, seriously

You're probably doing console.log("hit") inside your controllers to check if a route is being called. Stop that. There's a package that does this automatically, for every single request, with timing info included.

BASH
npm install morgan
JS
import morgan from "morgan";
app.use(morgan("dev")); // add this early, before your routes

Now every request logs itself automatically:

BASH
GET  /user/profile       200  12.453 ms
POST /test/submit        401   3.201 ms
GET  /api/nonexistent    404   1.102 ms

The "dev" format colors it — green for 200s, yellow for 300s, red for 400s and 500s. You see the full picture at a glance without touching a single controller.

For production, swap "dev" for "combined" — it logs IP addresses, user agents, and timestamps in Apache format. Useful when you need to debug what actually hit your server in deployment.

4. You're typing the same four commands every single day

Every time you start your project you open three terminals and type the same thing. CD here, npm run dev, CD there, npm run dev again, CD somewhere else, py app.py. Every single time.

Make a file. Two letters. Put it in your project root. Never type those commands again.

@echo off
start cmd /k "cd client && npm run dev"
start cmd /k "cd server && npm run dev"
start cmd /k "cd object-detection && py app.py"

Save it as s.bat on Windows or s.sh on Mac/Linux. Type s, hit enter, everything starts.

The point isn't the script itself — it's the habit. Any command you find yourself typing more than twice a day deserves a shortcut. Your fingers will thank you sometime around the 200th time you would have typed cd client && npm run dev.

None of this is groundbreaking. But the hours I've lost to port conflicts, silent 404s, and repetitive terminal commands — I'd like them back. Hope this saves you some of yours.