Database
Prisma
Introduction
JCC Express MVC supports Prisma as an ORM option via DB_ORM=prisma. Prisma uses its own schema (prisma/schema.prisma), migrations, and generated client — separate from JCC Eloquent models in app/Models/.
You can also use Prisma alongside JCC Eloquent by keeping DB_ORM=jcc and configuring database.prisma.service in app/Config/database.ts (the framework still registers a singleton Prisma client).
Enable Prisma
Option A — Prisma as primary ORM
DATABASE_URL is used by the Prisma CLI (prisma.config.ts). The framework does not pick a default runtime adapter. You must configure one explicitly (see below).
Built-in adapter factories (install the matching package when using PRISMA_ADAPTER or database.prisma.adapter):
PRISMA_ADAPTER | Package |
|---|---|
mariadb | @prisma/adapter-mariadb |
postgres | @prisma/adapter-pg + pg |
sqlite | @prisma/adapter-better-sqlite3 + better-sqlite3 |
libsql | @prisma/adapter-libsql |
Or configure the adapter in PrismaService / database.prisma.adapter instead of PRISMA_ADAPTER.
Option B — Prisma alongside JCC Eloquent
Keep DB_ORM=jcc for Knex/JCC models and ensure app/Config/database.ts includes:
PrismaServiceProvider registers the client whenever database.prisma.service is set.
Required packages
Initialize Prisma (new projects)
After installing the packages, scaffold Prisma in your app once from the project root. Skip this step if prisma/schema.prisma already exists.
Equivalent with npx:
This creates:
| File | Purpose |
|---|---|
prisma/schema.prisma | Your Prisma schema |
prisma.config.ts | CLI config (DATABASE_URL, migrations path) |
Use ./generated/prisma as the client output — not ../src/generated/prisma. JCC Express MVC imports the client from generated/prisma/client (see PrismaService below).
Set your database URL in .env before generating or migrating:
Then add app/Services/PrismaService.ts and wire database.prisma.service in app/Config/database.ts (see App service class).
Generate the client
Generate the client after prisma init and whenever the schema changes:
The generated client is written to generated/prisma/ (gitignored — run prisma:generate after clone/CI install).
Apply your first migration after generate:
App service class
The framework only injects an adapter when you set database.prisma.adapter or PRISMA_ADAPTER. Otherwise PrismaService owns the adapter:
When the framework does inject an adapter (options.adapter), it takes precedence over your fallback.
Configuring an adapter
Choose one approach:
1. In PrismaService (app-owned — recommended when you want full control)
2. PRISMA_ADAPTER env — uses a built-in factory:
3. database.prisma.adapter in app config:
Fully custom — pass any Prisma 7 adapter instance or factory:
database.prisma.adapter takes precedence over PRISMA_ADAPTER. If neither is set, the framework passes no adapter and PrismaService decides.
Framework adapter helpers
Built-in adapter factories:
| Export | Use |
|---|---|
createPrismaAdapter(name) | Build adapter for a named driver (PRISMA_ADAPTER) |
createMariaDbAdapter() | MySQL / MariaDB |
createPostgresAdapter() | PostgreSQL |
createSqliteAdapter() | SQLite file |
createLibSqlAdapter() | LibSQL / Turso |
The framework registers PrismaService as a singleton and aliases prisma and database.connection.
Using Prisma in controllers
Constructor injection (recommended):
Global helper:
Schema and migrations
Schema: prisma/schema.prisma
Migrations: prisma/migrations/
CLI config: prisma.config.ts
Equivalent npm scripts: prisma:generate, prisma:migrate, prisma:studio.
Framework wiring
| Piece | Location |
|---|---|
PrismaDriver | jcc-express-mvc/lib/Database/Drivers/PrismaDriver.ts |
| Driver adapters | jcc-express-mvc/lib/Database/Drivers/Prisma/adapters/ |
PrismaServiceProvider | jcc-express-mvc/lib/Database/PrismaServiceProvider.ts |
Database resolver | jcc-express-mvc/lib/Database/Database.ts (DB_ORM=prisma) |
When DB_ORM=prisma (or when database.prisma.service is set in app/Config/database.ts):
- Your
PrismaServiceclass is registered as a singleton. - The client is available via constructor injection,
app.resolve("prisma"), or the globalprisma()helper. - Knex / Sequelize / Mongoose setup is skipped so Prisma owns the database connection.
- The client disconnects gracefully on shutdown.