{"dataset":{"id":"00000000-0000-0000-0000-000000000025","slug":"express-best-practices","name":"Express best practices","description":"Source-linked guidance on Express fundamentals: routing, middleware, error-handling middleware, and production security and performance. Scoped to Express per the current official documentation; not a general Node.js corpus.","visibility":"public","version":1,"documentCount":5,"publisher":"Koskamo editorial","license":"Original summaries; linked sources retain their own terms.","reviewedAt":"2026-10-04T00:00:00.000Z","readOnly":true,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},"total":5,"documents":[{"title":"Production performance and reliability best practices","sourceUrl":"https://expressjs.com/en/advanced/best-practice-performance.html","text":"Set NODE_ENV to production: Express then caches view templates, caches CSS files generated from CSS extensions, and generates less verbose error messages — tests indicate this alone can improve performance by a factor of three. Use gzip compression via the compression middleware, but implement it at a reverse proxy level for high-traffic sites. Avoid synchronous functions in production; the --trace-sync-io flag prints a warning and stack trace whenever your app uses a synchronous API (for pre-production checks, not production). console.log() and console.error() are synchronous when the destination is a terminal or file; use the debug module with the DEBUG environment variable for debugging and a logging library like Pino for app activity. Handle exceptions with try-catch for synchronous code and with promises; do not listen for uncaughtException, because process state becomes unreliable, and do not use the deprecated domains module. Offload CPU-intensive work to worker threads through a fixed pool (for example with piscina) rather than a new worker per request. Run the latest Node.js LTS, ensure restarts with a process manager plus systemd (Restart=always and Environment=NODE_ENV=production in the unit file), and run a cluster with one instance per CPU core — instances do not share memory, so store state in a datastore like Redis. Cache request results with Varnish or Nginx, use a load balancer, and run Express behind a reverse proxy such as Nginx or HAProxy. Scope: Express. Reviewed October 4, 2026.","id":"express-best-practices:Production performance and reliability best practices","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Production security best practices","sourceUrl":"https://expressjs.com/en/advanced/best-practice-security.html","text":"Do not use deprecated or vulnerable versions: Express 2.x and 3.x are no longer maintained and their security issues will not be fixed. Use TLS to secure connections and data; Nginx is recommended to handle TLS, and Let's Encrypt is a free, automated certificate authority. Validate user input — prevent open redirects by checking URLs before res.redirect or res.location, for example comparing new URL(req.query.url).host against an allowed host. Use Helmet, middleware that sets security-related HTTP response headers such as Content-Security-Policy and Strict-Transport-Security and removes X-Powered-By; each header can be configured or disabled. Reduce fingerprinting with app.disable('x-powered-by'), though a sophisticated attacker can still detect Express. Use cookies securely: avoid the default session cookie name, and set the secure (HTTPS only) and httpOnly (not accessible to client JavaScript) options. express-session stores session data on the server and saves only the session ID in the cookie; cookie-session serializes the entire session into the cookie, so reserve it for small data and do not exceed 4093 bytes per domain. Protect login endpoints against brute force by blocking on consecutive failed attempts per username and IP address and on failed attempts per IP over time; rate-limiter-flexible provides tools for this. Since npm@6, npm reviews installs automatically; analyze the dependency tree with npm audit and consider Snyk. Scope: Express. Reviewed October 4, 2026.","id":"express-best-practices:Production security best practices","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Error handling and the four-argument middleware signature","sourceUrl":"https://expressjs.com/en/guide/error-handling.html","text":"Express catches errors thrown in synchronous code inside route handlers and middleware automatically. Handlers that return a Promise call next(value) when they reject or throw, and async functions always return a Promise, so their errors reach Express with no extra work; for a promise chain not returned from the handler, route the error yourself with .catch(next), and for callback APIs such as node:fs pass the error-first callback's error to next(). Passing anything to next() except the string 'route' marks the request as an error and skips remaining non-error-handling middleware. Define error-handling middleware like other middleware but with four arguments instead of three — (err, req, res, next) — and provide all four even when next is unused, or the function is interpreted as regular middleware. Define error handlers last, after other app.use() and route calls. Express adds a default error handler at the end of the stack: it writes the error with its stack trace to the client, omits the stack trace in production (NODE_ENV=production), and sets res.statusCode from err.status or err.statusCode, using 500 when the value is outside the 4xx or 5xx range. If res.headersSent is true, a custom handler must delegate to the default handler with next(err). Scope: Express. Reviewed October 4, 2026.","id":"express-best-practices:Error handling and the four-argument middleware signature","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Middleware and the request-response cycle","sourceUrl":"https://expressjs.com/en/guide/using-middleware.html","text":"An Express application is essentially a series of middleware function calls executed during the request-response cycle. Middleware functions have access to the request object (req), the response object (res), and the next middleware function, commonly named next. Middleware can execute any code, modify the request and response objects, end the request-response cycle, or pass control onward; if it does not end the cycle, it must call next(), otherwise the request will be left hanging. The types are application-level (bound with app.use() and app.METHOD()), router-level (bound to an express.Router() instance with router.use() and router.METHOD()), error-handling, built-in, and third-party. Middleware loads with an optional mount path, and multiple functions loaded together form a sub-stack at that mount point. next('route') skips the remaining middleware in a router stack and works only in functions loaded via app.METHOD() or router.METHOD(); next('router') exits the router instance entirely. Built-in middleware: express.static serves static assets, express.json parses JSON payloads, express.raw parses Buffer payloads, express.text parses text payloads, and express.urlencoded parses URL-encoded payloads. Scope: Express. Reviewed October 4, 2026.","id":"express-best-practices:Middleware and the request-response cycle","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Routing: methods, paths, parameters, and routers","sourceUrl":"https://expressjs.com/en/guide/routing.html","text":"Routing defines how an application's endpoints respond to client requests, using Express app object methods that correspond to HTTP methods: app.get() and app.post() for specific methods, app.all() for all HTTP methods, and app.use() to specify middleware as the callback. Multiple callbacks on one route require a next argument, and the function must call next() to hand off control, or next('route') to bypass the remaining route callbacks. Path matching uses path-to-regexp v8 and supports strings and regular expressions, named parameters (:name) populating req.params, wildcards (*name) captured as an array of segments, and braces for optional segments. Handlers may be a function, an array of functions, or combinations of both. Response methods such as res.send(), res.json(), and res.redirect() send a response and terminate the request-response cycle; if none is called, the client request is left hanging. app.route() creates chainable handlers for a single path, and express.Router builds modular, mountable route handlers — a mini-app; pass the mergeParams option to the Router constructor to access parent route path parameters. Scope: Express. Reviewed October 4, 2026.","id":"express-best-practices:Routing: methods, paths, parameters, and routers","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"}]}