Skip to content

Express.js Do's and Don'ts

Sometimes the clearest way to learn a convention is to see the right and wrong way side by side. This lesson presents Express do's and don'ts across the topics covered in this course.

Why Do's and Don'ts Matter

Express gives you enormous freedom, which is powerful, but also means it's easy to accidentally adopt patterns that work today but cause pain later, at scale, under load, or during an incident. The comparisons below highlight the most common ones.

// DON'T: business logic directly in the route
app.post('/orders', async (req, res) => {
  const total = req.body.items.reduce((s, i) => s + i.price * i.qty, 0);
  // ... 40 more lines of logic ...
});

// DO: delegate to a service
app.post('/orders', asyncHandler(async (req, res) => {
  const order = await orderService.create(req.body);
  res.status(201).json(order);
}));

Both versions work, but the second stays readable and testable as the business logic grows.

How to Use This Lesson

Each pair below shows:
  DON'T -> a common but problematic pattern
  DO    -> the recommended alternative, and why
  • These pairs summarize lessons covered in depth earlier in this course.
  • Not every "don't" is wrong in every context, use judgment for small scripts vs production APIs.
  • Revisit the linked lessons for the full reasoning behind each recommendation.

Do's and Don'ts at a Glance

The highest-impact comparisons across routing, middleware, and security.

Don't Do
Read req.body without express.json() Register body-parsing middleware before routes
Use GET to change data Use POST/PUT/PATCH/DELETE for mutations
Return raw stack traces to clients Log details server-side, send a generic message
Hardcode secrets in source Use environment variables via dotenv
Skip input validation Validate every route accepting client data
Use origin: '*' with credentials Use an explicit CORS origin allowlist

Routing and Middleware

Correct route order and consistent middleware placement prevent an entire class of subtle bugs.

  • DON'T register a parameterized route before a more specific literal one.
  • DO place literal paths (/users/new) before parameterized ones (/users/:id).
  • DON'T forget to call next() in non-terminal middleware.
  • DO make sure every middleware either responds or calls next() on every code path.

Errors and Security

Consistent, centralized handling beats scattered, one-off logic every time.

  • DON'T scatter ad-hoc res.status(500).send(...) calls throughout route files.
  • DO centralize error responses in one error-handling middleware.
  • DON'T store passwords with a fast, general-purpose hash.
  • DO use bcrypt (or similar) purpose-built password hashing.

Common Mistakes

  • Treating a "don't" as an absolute rule in every situation without considering context and scale.
  • Applying a "do" mechanically without understanding the underlying reasoning.
  • Ignoring these patterns until a real incident forces a rewrite under pressure.

Key Takeaways

  • Route order, middleware discipline, and centralized error handling prevent common classes of bugs.
  • Security do's, validation, CORS, secrets, hashing, are foundational, not optional polish.
  • Most "don'ts" in this list map to a specific, deeper lesson earlier in the course.

Pro Tip

Use this list as a quick pre-launch review checklist for any new Express project, most production incidents in Express apps trace back to one of these well-known patterns being skipped under time pressure.