Node Blueprint CLI supports three powerful ORMs, each with different strengths and use cases.
Available ORMs
Drizzle
Lightweight TypeScript ORM with SQL-like syntax and excellent performance
Prisma
Developer-friendly ORM with intuitive schema and powerful migrations
Mongoose
MongoDB object modeling with schema validation and middleware
ORM Comparison
| Feature | Drizzle | Prisma | Mongoose |
|---|
| Databases | PostgreSQL, MySQL | PostgreSQL, MySQL, MongoDB | MongoDB only |
| Type Safety | Excellent | Excellent | Good |
| Performance | Very Fast | Fast | Fast |
| Migration System | CLI-based | Built-in | Manual |
| Learning Curve | Moderate | Easy | Easy |
| Bundle Size | Small | Large | Medium |
| SQL-like Queries | Yes | No | No |
Drizzle ORM
Drizzle is a lightweight, type-safe ORM that feels like writing SQL but with full TypeScript support.
Features
- Zero dependencies in production
- SQL-like query syntax
- Excellent TypeScript inference
- Fast query execution
- Migration toolkit with
drizzle-kit
Generated Files
Drizzle projects include:
src/
├── db/
│ ├── index.ts # Database connection
│ ├── schema.ts # Schema exports
│ ├── seed.ts # Database seeding
│ └── schema/
│ ├── user-schema.ts # User table schema
│ └── token-schema.ts # Token table (if JWT enabled)
drizzle.config.ts # Drizzle Kit configuration
Configuration
Drizzle Config (drizzle.config.ts):
import { defineConfig } from "drizzle-kit";
if (!process.env.DATABASE_URL) {
throw new Error("DATABASE_URL is not set");
}
export default defineConfig({
dialect: "postgresql", // or "mysql"
schema: "./dist/src/db/schema/*",
out: "./migrations",
dbCredentials: {
url: process.env.DATABASE_URL
},
migrations: {
prefix: "timestamp",
table: "drizzle_migrations",
schema: "public"
}
});
Schema Definition
PostgreSQL User Schema (src/db/schema/user-schema.ts):
import { type InferSelectModel, type InferInsertModel, relations } from "drizzle-orm";
import { pgTable, text, timestamp, uuid, varchar, pgEnum } from "drizzle-orm/pg-core";
import { RoleEnum } from "../../enums/role-enum.js";
// create role enum type
const roleEnum = pgEnum("role", Object.values(RoleEnum) as [string, ...string[]]);
// schema definition
export const userSchema = pgTable("user", {
id: uuid("id").primaryKey().unique().notNull().defaultRandom(),
name: varchar("name", { length: 50 }),
email: varchar("email", { length: 255 }).notNull().unique(),
password: text("password").notNull(),
role: roleEnum().notNull().default(RoleEnum.USER),
createdAt: timestamp("created_at").notNull().defaultNow(),
updatedAt: timestamp("updated_at").notNull().defaultNow()
});
// types
export type SelectableUser = InferSelectModel<typeof userSchema>;
export type InsertableUser = InferInsertModel<typeof userSchema>;
MySQL User Schema:
import { mysqlTable, text, timestamp, varchar, mysqlEnum, int } from "drizzle-orm/mysql-core";
export const userSchema = mysqlTable("user", {
id: int("id").primaryKey().autoincrement(),
name: varchar("name", { length: 50 }),
email: varchar("email", { length: 255 }).notNull().unique(),
password: text("password").notNull(),
role: roleEnum.notNull().default(RoleEnum.USER),
createdAt: timestamp("created_at").notNull().defaultNow(),
updatedAt: timestamp("updated_at").notNull().defaultNow()
});
Projects with Drizzle include these scripts:{
"scripts": {
"db:seed": "tsx drizzle/seed.ts",
"db:generate": "npm run build && drizzle-kit generate",
"db:push": "drizzle-kit push",
"db:migrate": "tsx drizzle/migrate.ts",
"db:drop-migration": "drizzle-kit drop",
"db:introspect": "drizzle-kit introspect",
"db:studio": "drizzle-kit studio --port 4000"
}
}
Usage:
npm run db:generate - Generate migrations from schema
npm run db:push - Push schema changes directly to database
npm run db:studio - Open Drizzle Studio GUI on port 4000
npm run db:seed - Seed the database with initial data
Dependencies
{
"dependencies": {
"drizzle-orm": "^0.44.2"
},
"devDependencies": {
"drizzle-kit": "^0.31.1"
}
}
Prisma ORM
Prisma provides a modern ORM experience with an intuitive schema language and powerful developer tools.
Features
- Declarative schema with
.prisma files
- Auto-generated TypeScript client
- Built-in migration system
- Prisma Studio GUI for data browsing
- Excellent IntelliSense support
Generated Files
Prisma projects include:
prisma/
├── schema.prisma # Database schema
├── prisma-client.ts # Client configuration
└── seed.ts # Database seeding
Schema Definition
Prisma Schema (prisma/schema.prisma):
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql" // or "mysql" or "mongodb"
url = env("DATABASE_URL")
}
enum RoleEnum {
admin
user
}
model User {
id String @id @unique @default(uuid())
name String? @db.VarChar(50)
email String @unique @db.VarChar(255)
password String
role RoleEnum @default(user)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
MongoDB Schema:
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String?
email String @unique
password String
role RoleEnum @default(user)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
Client Configuration (prisma/prisma-client.ts):import { PrismaClient } from '@prisma/client';
const prismaClientSingleton = () => {
return new PrismaClient();
};
type PrismaClientSingleton = ReturnType<typeof prismaClientSingleton>;
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClientSingleton | undefined;
};
const prisma = globalForPrisma.prisma ?? prismaClientSingleton();
export default prisma;
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
This singleton pattern ensures only one Prisma Client instance exists during development.
Projects with Prisma include these scripts:{
"scripts": {
"db:seed": "tsx prisma/seed.ts",
"db:generate": "prisma generate",
"db:push": "prisma db push",
"db:migrate": "prisma migrate dev",
"db:reset": "prisma migrate reset",
"db:introspect": "prisma db pull",
"db:deploy": "prisma migrate deploy",
"db:studio": "prisma studio --port 4000"
}
}
Usage:
npm run db:generate - Generate Prisma Client from schema
npm run db:push - Push schema changes without migrations
npm run db:migrate - Create and apply migrations
npm run db:studio - Open Prisma Studio GUI on port 4000
npm run db:seed - Seed the database with initial data
Dependencies
{
"dependencies": {
"@prisma/client": "^6.9.0"
},
"devDependencies": {
"prisma": "^6.9.0"
}
}
Mongoose ORM
Mongoose is the de facto ODM (Object Document Mapper) for MongoDB with schema validation and middleware hooks.
Features
- Schema-based modeling for MongoDB
- Built-in validation and casting
- Middleware (pre/post hooks)
- Query builders and population
- Schema plugins and virtuals
Generated Files
Mongoose projects include:
src/
├── config/
│ └── db.ts # MongoDB connection
├── models/
│ ├── user-model.ts # User schema and model
│ ├── token-model.ts # Token model (if JWT enabled)
│ └── seed.ts # Database seeding
└── enums/
└── role-enum.ts # Role enumeration
Model Definition
User Model (src/models/user-model.ts):
import { Schema, model, Document } from "mongoose";
import { RoleEnum } from "../enums/role-enum.js";
// Define User interface
interface IUser extends Document {
name?: string;
email: string;
password: string;
role: RoleEnum;
createdAt: Date;
updatedAt: Date;
}
// Mongoose Schema
const userSchema = new Schema<IUser>(
{
name: { type: String, maxlength: 50, trim: true },
email: { type: String, required: true, unique: true, maxlength: 255, lowercase: true },
password: { type: String, required: true, select: false },
role: { type: String, enum: RoleEnum, default: RoleEnum.USER },
},
{
timestamps: true,
toJSON: {
transform: function (doc, ret) {
delete ret.password;
return ret;
},
}
}
);
// create and export User model
const User = model<IUser>("User", userSchema);
export default User;
Database Connection
Connection Handler (src/config/db.ts):
import mongoose from "mongoose";
const connectDb = async () => {
try {
const dbUrl = process.env.DATABASE_URL;
if (!dbUrl) {
throw new Error("DATABASE_URL is not defined");
}
await mongoose.connect(dbUrl);
console.log("✅ MongoDB connected successfully");
} catch (error) {
console.error("❌ MongoDB connection failed:", error);
process.exit(1);
}
};
export default connectDb;
Projects with Mongoose include:{
"scripts": {
"db:seed": "tsx src/models/seed.ts"
}
}
Mongoose migrations are typically handled manually or with third-party tools.
Dependencies
{
"dependencies": {
"mongoose": "^8.15.2"
},
"devDependencies": {
"@types/mongoose": "^5.11.97"
}
}
Mongoose can only be used with MongoDB. When selecting MongoDB as your database, Mongoose will be your only ORM option.
Choosing an ORM
- You want maximum performance and control
- You prefer SQL-like query syntax
- You need a small bundle size
- You’re comfortable with SQL concepts
- You want minimal runtime overhead
- You want the best developer experience
- You prefer declarative schema definitions
- You need powerful migration tools
- You want excellent IDE support
- You value simplicity over bundle size
- You’re using MongoDB
- You need schema validation and middleware
- You want document-oriented patterns
- You’re familiar with MongoDB ecosystems
- You need virtuals and query helpers
Quick Start
Run the CLI
npx create-node-blueprint my-app
Select your ORM
Choose Drizzle, Prisma, or Mongoose when prompted
Generate schema/client
# For Drizzle
npm run db:generate
# For Prisma
npm run db:generate
Run migrations or push schema
# For Drizzle
npm run db:push
# For Prisma
npm run db:push