๐—•๐˜‚๐—ถ๐—น๐—ฑ๐—ถ๐—ป๐—ด ๐—” ๐—ฃ๐—ฟ๐—ผ๐—ฑ๐˜‚๐—ฐ๐˜๐—ถ๐—ผ๐—ป ๐—ฅ๐—ฒ๐—ฎ๐—ฑ๐˜† ๐—•๐—ฎ๐—ฐ๐—ธ๐—ฒ๐—ป๐—ฑ

You need data integrity for a finance app. One bug will crash your server. Weak types will corrupt your database.

I built a backend using Express, TypeScript, and Zod. Here is how to make it stable.

Stop writing try/catch in every controller. It clutters your code. Use a wrapper function. It catches errors and sends them to a global handler.

Avoid using "any" for request objects. It kills type safety. Use declaration merging. This adds user IDs and request IDs to the Express Request object.

Keep validation out of your logic. Use a middleware factory with Zod. It checks data before your controller sees it. This keeps your routes clean.

One global error middleware handles everything. It catches Zod errors and custom app errors. You stop writing repetitive response strings.

Middleware order is key.

This architecture gives you three wins.

How do you structure your Express apps? Do you use declaration merging or a different pattern?

Source: https://dev.to/singh_kashish/architecting-a-production-ready-express-typescript-backend-type-augmentation-global-errors-and-7n1