Engine

Engine

The backend layer — NestJS on Fastify, Drizzle ORM, one PostgreSQL schema per customer.

Engine is the backend layer. It is a configuration-driven API server: clone it, fill in .env, define your JSON policies, and you have a production-shaped backend to build your product against. It is multi-tenant internally — each customer account gets its own PostgreSQL schema — but it makes no assumptions about what your product does.

The stack, and why

ChoiceOverReason
FastifyExpressThroughput — see below
Drizzle ORMPrisma / TypeORMThin layer over SQL, no separate query engine
PostgreSQL schemasTenant-id columnsIsolation enforced by the database
NestJSBare NodeModule boundaries a team can share

Throughput

These are the Engine's own benchmark figures, measured on the combined stack rather than the framework alone:

StackRequests / second
Express + TypeORM12,000
Express + Prisma18,000
Fastify + Drizzle ORM65,000

Treat these as directional. They come from our benchmark, on our hardware, with our handlers — the honest use for them is comparing the three combinations against each other, not predicting your production numbers.

For framework-level figures measured by someone other than us, Fastify publishes its own comparison at fastify.dev/benchmarks, which it labels an illustrative comparison.

Strict by default

Engine has no hardcoded fallbacks. Required configuration that is missing fails the boot, validated by Joi at startup in src/config/validation.schema.ts.

This is deliberate: you find out about a missing JWT_ACCESS_SECRET when the process refuses to start, not from a 500 in production three hours later.

What is built, and what is not

Built and working: JWT auth, five SSO providers, module-based RBAC, tenant provisioning, sliding-window refresh sessions, transactional email, queues on Redis, local file storage.

Interfaces exist but adapters do not: billing (Stripe, Zoho, Razorpay) and cloud storage (S3, GCS). Storage falls back to a working LocalStorageAdapter. See Contributing.