DEV Community

Cover image for πŸŽ‰ Goodbye asyncHandler: Native Async Support in Express 5
Mahmudur Rahman
Mahmudur Rahman

Posted on

πŸŽ‰ Goodbye asyncHandler: Native Async Support in Express 5

Express has long been a staple in the Node.js ecosystem, powering thousands of APIs and web applications. However, until recently, handling asynchronous route logic in Express has always felt a bit clunky β€” particularly when it comes to error handling in async functions.

But good news: Express 5 finally brings first-class support for async/await with native promise error handling! That means you can now write clean, modern async route handlers without wrappers like asyncHandler().
In this post, we’ll walk through:

  • 🀯 The problem in Express 4
  • βœ… The solution in Express 5
  • πŸ› οΈ Migration tips
  • πŸ§ͺ Real-world example

🀯 The Problem in Express 4
In Express 4, writing async handlers directly like this:

app.get('/users', async (req, res) => {
  const users = await getUsersFromDb(); // what if this throws?
  res.json(users);
});
Enter fullscreen mode Exit fullscreen mode

would result in an unhandled promise rejection if getUsersFromDb() throws or rejects.

Why? Because Express 4 does not understand that async functions return promises. It doesn’t await them or catch their rejections automatically.
Workaround: Using asyncHandler()
To deal with this, most devs used a helper like:

const asyncHandler = fn => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
};

Enter fullscreen mode Exit fullscreen mode

Then you’d wrap every route:

app.get('/users', asyncHandler(async (req, res) => {
  const users = await getUsersFromDb();
  res.json(users);
}));
Enter fullscreen mode Exit fullscreen mode

Clunky, right?

βœ… The Fix in Express 5
In Express 5, this boilerplate is no longer needed. You can now write:

app.get('/users', async (req, res) => {
  const users = await getUsersFromDb(); // if this throws, Express 5 will catch it
  res.json(users);
});
Enter fullscreen mode Exit fullscreen mode

πŸŽ‰ Express 5 automatically awaits promises and forwards errors to the error handler!

πŸ§ͺ Real-World Example
Let’s say you have this:

app.get('/profile', async (req, res) => {
  const user = await findUserById(req.query.id);
  if (!user) throw new Error('User not found');
  res.json(user);
});
Enter fullscreen mode Exit fullscreen mode

If anything throws (like a DB error), Express 5 will automatically send it to your error middleware:

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).json({ message: err.message });
});

Enter fullscreen mode Exit fullscreen mode

No more asyncHandler. No more accidental unhandled rejections.
πŸ› οΈ Migration Tips
If you're upgrading from Express 4 to 5:

  1. Remove asyncHandler() wrappers β€” just use async route functions directly.
  2. Double-check your error middleware β€” Express 5 continues to use the (err, req, res, next) signature.
  3. Update your dependencies β€” install the latest Express version:
npm install express@next

Enter fullscreen mode Exit fullscreen mode

⚠️ At the time of writing, Express 5 is in beta (express@5.0.0-beta.x). Keep an eye on the official changelog for production readiness.

app.use(async (req, res, next) => {
  const isValid = await validateToken(req.headers.authorization);
  if (!isValid) throw new Error('Unauthorized');
  next();
});

Enter fullscreen mode Exit fullscreen mode

Again, no try/catch needed β€” Express 5 has your back.
🧾 Summary
βœ… Express 5 brings native async/await support
βœ… No need for async wrappers
βœ… Clean, modern error handling
βœ… Works in both routes and middleware
βœ… Big win for developer experience!

πŸ“š References

Add Basic Error Handling to an Express 5 App
πŸ™Œ Conclusion
Express 5 may not seem flashy at first glance, but this feature alone dramatically simplifies writing clean, maintainable APIs with modern JavaScript. If you’ve been juggling asyncHandler utilities in Express 4, it's time to celebrate and simplify.

Happy coding!
✍️ Follow me on Dev.to or GitHub for more Node.js tips, architecture guides, and backend tutorials.

Top comments (0)