Every SaaS product eventually needs the same backend infrastructure. Authentication flows, session management, multi-tenancy, notification channels, rate limiting, audit logging, file storage — the list is long and the work is repetitive. Building these systems correctly takes weeks. Building them incorrectly means paying the debt later, usually at the worst possible time. Express Boilerplate exists to close that gap: a complete, well-structured backend foundation that lets development begin at the business logic layer instead of the infrastructure layer.
The project covers the full surface area of a modern SaaS API across 35+ domain modules. Each module is self-contained, independently testable, and follows a consistent internal structure — service, DTO, types, messages, enums, tests. That consistency might feel like overhead on the third module. By the thirty-fifth, it means any developer can open an unfamiliar module and immediately know where to find anything without reading a line of documentation.
Architecture
The most deliberate decision in the project is the separation between business logic and framework. Everything under modules/ is completely framework-agnostic — no Express imports, no HTTP context, no runtime-specific APIs. Express-specific concerns like middleware, error handling, and request parsing live in a separate modules_express/ adapter layer. The result is a core that can be tested as pure TypeScript functions and reused across different runtimes. The same modules/ directory is shared with a parallel Next.js boilerplate, where identical business logic runs inside Next.js Route Handlers. Two runtimes, one domain layer.
Routes are split into two groups: /api/system/ for platform-level operations and /api/tenant/ for tenant-scoped operations. This separation reflects the actual access model of a SaaS product — some things belong to the platform, some things belong to the tenant context.
Authentication
Authentication is one of the most underestimated surfaces in backend development. Getting a user to log in is straightforward. Supporting every auth pattern a real product needs — across consumer and enterprise customers — is a different problem entirely. The boilerplate covers JWT with OTP and TOTP two-factor authentication, passkeys via WebAuthn for passwordless login, OAuth 2.0 for social and SSO flows, SAML 2.0 for enterprise identity providers, and an admin impersonation system for support workflows. Session lifecycle is managed through the user_session module with Redis-backed caching, token refresh, and revocation support.
Multi-Tenancy
Multi-tenancy is not an add-on feature — it is a first-class architectural concern throughout the project. Every tenant gets isolated settings, configurable branding with logo and colors, custom domain support with DNS TXT record verification, a full membership system with role-based access, email-based invitation workflows, subscription plans with feature flags and billing cycle management, and API usage quota tracking. Tenant data can be fully exported at any time. The tenant_session module binds user sessions to tenant context, ensuring that authorization decisions are always made within the correct scope.
Notifications and Infrastructure
The notification layer treats each channel as an independent, swappable module. Transactional email runs through Nodemailer or SendGrid depending on configuration. SMS is handled via Twilio. Web push notifications use the web-push library with proper VAPID key management. In-app notifications are stored in the database and surfaced through their own API. None of these are coupled — disabling or replacing one does not affect the others.
Background jobs run through BullMQ backed by Redis, with an idempotency key system for safe retries. File uploads target any S3-compatible storage provider. Structured logging is handled by Winston with Morgan for HTTP request logging. Rate limiting is plan-aware, meaning different subscription tiers can have different limits on the same endpoint without custom middleware logic.
Security
Security is applied at every layer rather than added at the edges. All incoming payloads are validated with Zod schemas before reaching service code. HTTP security headers are set via Helmet. CSRF protection is enabled. Passwords are hashed with bcrypt. Redis-backed rate limiting protects against brute force and abuse. An immutable audit trail records all critical operations with actor, action, and timestamp. Errors are handled through a centralized middleware that distinguishes operational errors from unexpected failures, preventing internal state from leaking into API responses.
The Result
A developer starting a SaaS product with this as the foundation writes their first domain-specific feature on day one. The infrastructure is already there — correct, consistent, and ready to extend.
Newsletter
Stay updated! Get all the latest and greatest posts delivered straight to your inbox