Skip to content

Node.js

Patterns for Node.js backend development: building Express servers, loading files and SQL queries, making HTTP calls and RPC, organizing modules, managing child processes, server-side rendering, fixing npm vulnerabilities, and publishing packages.

Express.js

Patterns for building Express.js servers: application setup, middleware composition, modular architecture, routing conventions, error handling, and server lifecycle.

  • Express.js Core Patterns: App creation, settings, middleware pipelines, and route mounting. Use when starting or structuring an Express server.
  • Fractal Express Pattern: Use full Express instances — not Routers — as composable modules. Use when structuring a server with multiple independently testable concerns.
  • File-System Auto-Routing: Map directory structure to URL routes automatically, with [param] directory conventions. Use when you want Next.js-style file routing in plain Express.
  • Promisified Server Startup: Wrap server.listen() in a promise returning url, port, and listener. Use when starting an HTTP server with await.
  • Auto Port Selection: Find an available port when the default is occupied. Use when running dev servers that may conflict on a fixed port.
  • HTTP Error Classes: Class hierarchy for HTTP errors with automatic status codes and attachable details. Use when throwing structured errors that map to HTTP status codes.
  • Express Utility Handlers: Reusable middleware for blocking requests until async startup completes and sending 404 responses. Use when gating routes behind preconditions.
  • Request Logging Middleware: One structured log entry per request using canonical log lines. Use when replacing scattered console.log() calls with queryable structured logs.
  • Proxy Middleware with Fallthrough: Proxy that falls through to the next handler on 404. Use when composing multiple backend servers behind a single entry point.
  • WHATWG Request/Response Adapter: Adapt Express to standard WHATWG Request/Response objects. Use when writing handlers portable across Node.js, Deno, and Cloudflare Workers.

File Utilities

Patterns for reading and resolving file paths in Node.js. These utilities make it easy to load static resources like SQL queries, templates, and config files using paths relative to the calling module.

  • file() Utility: Synchronous file reading that resolves paths relative to the calling module, not the working directory. Use when loading SQL queries, templates, or config files at module init time.
  • File Path Resolver: Single resolve() function that handles absolute, relative, and module paths from the caller's location. Use when you need flexible path resolution beyond path.join().
  • Dotpath Template Tag: Tagged template literal for constructing file paths with interpolation. Use when building paths from dynamic segments more cleanly than path.join() calls.

HTTP and RPC

Patterns for Node.js HTTP services.

  • Simple RPC: Lightweight RPC layer using an ES6 Proxy client and Express middleware — call server methods as if local, no schemas required. Use when building internal APIs between browser and Node.js.

Modules

Patterns for organizing and configuring Node.js modules: bridging ESM and CommonJS, structuring packages with subpath exports, and managing multi-package repositories with npm workspaces.

  • CJS Utilities in ESM: One-call bridge that gives ESM modules require, __filename, and __dirname. Use when ESM code needs CJS utilities or must load a CJS-only package.
  • Node.js Module Patterns: ESM-first package.json setup, subpath exports, and private import aliases. Use when configuring module systems for a Node.js project.
  • npm Workspaces: Multi-package repository management with npm's built-in workspace support. Use when a repo contains multiple packages that share code.

Process Management

Patterns for spawning, managing, and cleaning up child processes in Node.js. Covers the built-in child_process module, ergonomic wrappers for shell command execution, process tree lifecycle management, and CLI architecture.

  • Node.js child_process Functions: Guide to spawn, exec, execFile, and fork — choosing the right function based on synchronicity and shell usage. Use when running external commands from Node.js.
  • Child Process Cleanup: Reliable termination of child process trees with pipe cleanup and exit handlers. Use when spawning long-lived processes that must not outlive the parent.
  • Pretty Error Formatting: Turn dense stack traces into readable, color-highlighted output. Use in CLI tools or dev scripts where default Node.js errors are hard to read.
  • Shell Command Tag: Tagged template literal that builds shell commands with automatic escaping to prevent injection. Use when executing shell commands with dynamic values from Node.js.
  • CLI Subcommands: Directory-mirrored CLI architecture using Commander.js executableFile with co-located resources. Use when building a CLI tool with multiple nested commands.
  • Watch Mode: Automatic rebuilds and retests on file changes using npm script watchers. Use when developing locally and you want continuous feedback on changes.

SQL

Patterns for organizing SQL queries and database access in Node.js applications.

  • SQL Queries in Separate Files: Store SQL in .sql files for editor syntax highlighting and linting support. Use when queries are complex enough to benefit from dedicated files.
  • Named SQL Parameters: Replace positional ? placeholders with readable :param names in SQL queries. Use when writing queries that accept input values.
  • Query Objects and Resource Classes: Namespace SQL queries into objects and wrap CRUD operations in static Resource class methods. Use when building a data access layer.
  • Database Migrations: Versioned, reversible schema changes with a custom runner: each migration is a timestamped directory of apply.sql/unapply.sql scripts, and applied state is tracked in a database table. Use when you want plain-SQL migrations without a framework.

Server-Side Rendering

Patterns for server-side HTML rendering in Node.js applications.

  • EJS with Includes and require(): Enhanced EJS rendering with require() support inside templates, recursive includes, and linting. Use when server-side rendering HTML, SQL, or other structured text in Node.js.

npm Tooling

  • Fix npm Vulnerabilities: Minimal, controlled fixes for npm audit vulnerabilities via package.json edits and overrides. Use when the user wants to resolve npm security warnings.
  • Publish to GitHub Packages: GitHub Actions workflow that publishes npm packages on version tags. Use when automating package publishing to GitHub Packages.

See also

  • Unit-of-Work Telemetry: Request-scoped structured logging and function-level tracing via AsyncLocalStorage.
  • Phased Migrations: Phased migration patterns for database schema changes.
  • Browser HTTP: Fetch wrapper and Axios client for the browser side of client-server communication.
  • Vite HTML Includes Plugin: Build-time HTML composition as an alternative to server-side rendering.
  • HTML Includes: Runtime HTML composition via web components for browser-side page assembly.
  • GitHub: GitHub CLI, Actions, PRs, and CI workflows.