Database (SQL)
ExisJS provides zero-config, native integrations for the most popular SQL databases and ORMs in the Node.js ecosystem. Instead of writing boilerplate connection logic, ExisJS automatically manages your connection pools using the DATABASE_URL environment variable.
Because these plugins are completely zero-config, you do NOT need to register them in your server.ts file! They lazily initialize their connection pools the exact moment you first query them.
The framework provides first-class plugins for Drizzle ORM, Prisma, and raw PostgreSQL (postgres.js).
Environment Variables
All SQL plugins securely read your connection string from your .env file.
Before using any of the plugins below, ensure you have your Postgres connection string set:
# Your PostgreSQL connection stringDATABASE_URL="postgres://user:password@localhost:5432/my_database"1. Drizzle ORM (Recommended)
Drizzle ORM is the recommended database solution for ExisJS. It provides maximum type safety, unparalleled performance, and zero overhead.
Installation
npm install drizzle-orm postgresnpm install -D drizzle-kitUsage
Simply define your schema and call the native drizzle() integration helper. ExisJS will automatically initialize a highly optimized postgres.js connection pool using your DATABASE_URL environment variable.
import { drizzle } from 'exisjs/drizzle'import { pgTable, serial, text, varchar } from 'drizzle-orm/pg-core'
// 1. Define your schemaexport const users = pgTable('users', { id: serial('id').primaryKey(), fullName: text('full_name'), phone: varchar('phone', { length: 256 }),})
const schema = { users }
// 2. Initialize the client (Zero Config!)// ExisJS automatically reads process.env.DATABASE_URLexport const db = drizzle(schema)Now you can use db in your routes:
Functional Paradigm
import { controller, route } from 'exisjs/router'import { db, users } from '../../db'
export default controller({ listUsers: route.get('/', { async handle() { return await db.select().from(users) } })})Class-Based (OOP) Paradigm
import { Controller, Get } from 'exisjs/decorators'import { db, users } from '../../db'
@Controller()export default class UsersController { @Get('/') async listUsers() { return await db.select().from(users) }}2. Prisma ORM
If you prefer a schema-first approach, ExisJS includes a zero-config wrapper for Prisma.
Installation
npm install @prisma/clientnpm install -D prismaInitialize your schema:
npx prisma initUsage
Use the native prisma() helper to instantiate a singleton PrismaClient that automatically suppresses excessive logging in edge environments and optimally manages the connection.
import { prisma } from 'exisjs/prisma'
// Zero config singleton initializationexport const db = prisma()3. Raw PostgreSQL (postgres.js)
If you don't want to use an ORM and prefer writing raw SQL for maximum performance, ExisJS bundles a zero-config integration for the blazing fast postgres.js driver.
Installation
npm install postgresUsage
Import the tagged template literal sql from exisjs/postgres. The first time you use it, ExisJS will instantly boot up a connection pool using DATABASE_URL.
Functional Paradigm
import { controller, route } from 'exisjs/router'import { sql } from 'exisjs/postgres'
export default controller({ getUser: route.get('/:id', { async handle(req) { // Write raw SQL with native parameterization! const users = await sql`SELECT * FROM users WHERE id = ${req.params.id}` return users[0] } })})Class-Based (OOP) Paradigm
import { Controller, Get, Param } from 'exisjs/decorators'import { sql } from 'exisjs/postgres'
@Controller()export default class UsersController { @Get('/:id') async getUser(@Param('id') id: string) { // Write raw SQL with native parameterization! const users = await sql`SELECT * FROM users WHERE id = ${id}` return users[0] }}Customizing Connection Options
If you need to pass custom options to the Postgres connection pool (like SSL config or max pool sizes), call configurePostgres(options) before you run your first query (e.g. inside your server.ts onStart hook).
import { exis } from 'exisjs'import { configurePostgres } from 'exisjs/postgres'
export default exis({ async onStart() { // Initialize with custom connection limits configurePostgres({ max: 20, idle_timeout: 30000, ssl: process.env.NODE_ENV === 'production' ? 'require' : false }) }})