opção

ORM SQL com segurança de tipos para TypeScript, sem sobrecarga de tempo de execução

...Expandir tudo
70
Tempo atualizado 29 de Junho de 2026

Sobre drizzle-orm

O Drizzle ORM é uma biblioteca moderna de mapeamento objeto-relacional (ORM) que prioriza o TypeScript, projetada para proporcionar interações seguras em termos de tipos com bancos de dados SQL, mantendo zero sobrecarga de tempo de execução. Ela resolve o problema comum de erros de tempo de execução e incompatibilidade de tipos ao trabalhar com bancos de dados relacionais, oferecendo verificação de tipos em tempo de compilação e uma sintaxe semelhante à do SQL que os desenvolvedores podem usar diretamente no TypeScript. Isso torna as operações com bancos de dados mais previsíveis e reduz a probabilidade de bugs em ambientes de execução sem servidor ou de borda, onde eficiência e dependências mínimas são fundamentais.

O ORM oferece vários recursos e funcionalidades importantes. Ele suporta diversos bancos de dados, incluindo PostgreSQL, MySQL e SQLite, permitindo que os desenvolvedores escolham o driver adequado para seu projeto. O Drizzle ORM fornece um sistema flexível de definição de esquemas com uma variedade de tipos de coluna mapeados diretamente para tipos do TypeScript, possibilitando tipagem forte para consultas, inserções e atualizações. Ele também inclui recursos para definir relações entre tabelas, como relações um-para-muitos, e oferece suporte à inferência de tipos tanto para operações de seleção quanto de inserção. Além disso, o Drizzle Kit pode ser usado para migrações, facilitando o gerenciamento de alterações no esquema do banco de dados ao longo do tempo. Seu design sem dependências garante uma integração leve aos projetos e desempenho ideal em ambientes com restrições.

Os usuários-alvo incluem desenvolvedores de TypeScript que criam aplicativos que interagem com bancos de dados SQL e exigem segurança de tipos forte e comportamento previsível. O Drizzle ORM é particularmente útil para quem desenvolve aplicativos sem servidor, funções de borda ou projetos em que o desempenho e a sobrecarga mínima de tempo de execução são importantes. Ele é adequado para cenários que vão desde simples aplicativos CRUD até sistemas mais complexos com modelos de dados relacionais e padrões avançados de consulta, oferecendo uma abordagem confiável e fácil de manter para interações com bancos de dados, ao mesmo tempo em que aproveita o sistema de tipos do TypeScript.

Perguntas frequentes

Como faço para instalar e configurar o Drizzle ORM?

Você pode instalar o ORM principal usando o npm com `npm install drizzle-orm` e, em seguida, instalar o driver de banco de dados apropriado para o seu banco de dados, como `pg` para PostgreSQL ou `mysql2` para MySQL. Para migrações, instale o `drizzle-kit` como uma dependência de desenvolvimento.

Quais bancos de dados são compatíveis com o Drizzle ORM?

O Drizzle ORM oferece suporte a PostgreSQL, MySQL e SQLite por meio de seus respectivos drivers de banco de dados.

O Drizzle ORM adiciona sobrecarga de tempo de execução?

Não, o Drizzle ORM foi projetado para não causar sobrecarga de tempo de execução, contando com a verificação de tipos em tempo de compilação para garantir segurança e correção.

Posso definir relações entre tabelas?

Sim, o Drizzle ORM oferece suporte à definição de relações como “um para muitos”, permitindo que você modele dados relacionais em TypeScript com segurança.

O Drizzle ORM é adequado para ambientes sem servidor ou de borda?

Sim, ele é otimizado para desempenho em ambientes sem servidor e de borda devido ao seu design sem dependências e ao tratamento eficiente de consultas.

Ver no GitHub

Drizzle ORM

Modern TypeScript-first ORM with zero dependencies, compile-time type safety, and SQL-like syntax. Optimized for edge runtimes and serverless environments.

Quick Start

Installation

# Core ORMnpm install drizzle-orm# Database driver (choose one)npm install pg            # PostgreSQLnpm install mysql2        # MySQLnpm install better-sqlite3 # SQLite# Drizzle Kit (migrations)npm install -D drizzle-kit

Basic Setup

// db/schema.tsimport { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';export const users = pgTable('users', {  id: serial('id').primaryKey(),  email: text('email').notNull().unique(),  name: text('name').notNull(),  createdAt: timestamp('created_at').defaultNow(),});// db/client.tsimport { drizzle } from 'drizzle-orm/node-postgres';import { Pool } from 'pg';import * as schema from './schema';const pool = new Pool({ connectionString: process.env.DATABASE_URL });export const db = drizzle(pool, { schema });

First Query

import { db } from './db/client';import { users } from './db/schema';import { eq } from 'drizzle-orm';// Insertconst newUser = await db.insert(users).values({  email: '[email protected]',  name: 'John Doe',}).returning();// Selectconst allUsers = await db.select().from(users);// Whereconst user = await db.select().from(users).where(eq(users.id, 1));// Updateawait db.update(users).set({ name: 'Jane Doe' }).where(eq(users.id, 1));// Deleteawait db.delete(users).where(eq(users.id, 1));

Schema Definition

Column Types Reference

PostgreSQLMySQLSQLiteTypeScript
serial()serial()integer()number
text()text()text()string
integer()int()integer()number
boolean()boolean()integer()boolean
timestamp()datetime()integer()Date
json()json()text()unknown
uuid()varchar(36)text()string

Common Schema Patterns

import { pgTable, serial, text, varchar, integer, boolean, timestamp, json, unique } from 'drizzle-orm/pg-core';export const users = pgTable('users', {  id: serial('id').primaryKey(),  email: varchar('email', { length: 255 }).notNull().unique(),  passwordHash: varchar('password_hash', { length: 255 }).notNull(),  role: text('role', { enum: ['admin', 'user', 'guest'] }).default('user'),  metadata: json('metadata').$type<{ theme: string; locale: string }>(),  isActive: boolean('is_active').default(true),  createdAt: timestamp('created_at').defaultNow().notNull(),  updatedAt: timestamp('updated_at').defaultNow().notNull(),}, (table) => ({  emailIdx: unique('email_unique_idx').on(table.email),}));// Infer TypeScript typestype User = typeof users.$inferSelect;type NewUser = typeof users.$inferInsert;

Relations

One-to-Many

import { pgTable, serial, text, integer } from 'drizzle-orm/pg-core';import { relations } from 'drizzle-orm';export const authors = pgTable('authors', {  id: serial('id').primaryKey(),  name: text('name').notNull(),});export const posts = pgTable('posts', {  id: serial('id').primaryKey(),  title: text('title').notNull(),  authorId: integer('author_id').notNull().references(() => authors.id),});export const authorsRelations = relations(authors, ({ many }) => ({  posts: many(posts),}));export const postsRelations = relations(posts, ({ one }) => ({  author: one(authors, {    fields: [posts.authorId],    references: [authors.id],  }),}));// Query with relationsconst authorsWithPosts = await db.query.authors.findMany({  with: { posts: true },});

Many-to-Many

export const users = pgTable('users', {  id: serial('id').primaryKey(),  name: text('name').notNull(),});export const groups = pgTable('groups', {  id: serial('id').primaryKey(),  name: text('name').notNull(),});export const usersToGroups = pgTable('users_to_groups', {  userId: integer('user_id').notNull().references(() => users.id),  groupId: integer('group_id').notNull().references(() => groups.id),}, (table) => ({  pk: primaryKey({ columns: [table.userId, table.groupId] }),}));export const usersRelations = relations(users, ({ many }) => ({  groups: many(usersToGroups),}));export const groupsRelations = relations(groups, ({ many }) => ({  users: many(usersToGroups),}));export const usersToGroupsRelations = relations(usersToGroups, ({ one }) => ({  user: one(users, { fields: [usersToGroups.userId], references: [users.id] }),  group: one(groups, { fields: [usersToGroups.groupId], references: [groups.id] }),}));

Queries

Filtering

import { eq, ne, gt, gte, lt, lte, like, ilike, inArray, isNull, isNotNull, and, or, between } from 'drizzle-orm';// Equalityawait db.select().from(users).where(eq(users.email, '[email protected]'));// Comparisonawait db.select().from(users).where(gt(users.id, 10));// Pattern matchingawait db.select().from(users).where(like(users.name, '%John%'));// Multiple conditionsawait db.select().from(users).where(  and(    eq(users.role, 'admin'),    gt(users.createdAt, new Date('2024-01-01'))  ));// IN clauseawait db.select().from(users).where(inArray(users.id, [1, 2, 3]));// NULL checksawait db.select().from(users).where(isNull(users.deletedAt));

Joins

import { eq } from 'drizzle-orm';// Inner joinconst result = await db  .select({    user: users,    post: posts,  })  .from(users)  .innerJoin(posts, eq(users.id, posts.authorId));// Left joinconst result = await db  .select({    user: users,    post: posts,  })  .from(users)  .leftJoin(posts, eq(users.id, posts.authorId));// Multiple joins with aggregationimport { count, sql } from 'drizzle-orm';const result = await db  .select({    authorName: authors.name,    postCount: count(posts.id),  })  .from(authors)  .leftJoin(posts, eq(authors.id, posts.authorId))  .groupBy(authors.id);

Pagination & Sorting

import { desc, asc } from 'drizzle-orm';// Order byawait db.select().from(users).orderBy(desc(users.createdAt));// Limit & offsetawait db.select().from(users).limit(10).offset(20);// Pagination helperfunction paginate(page: number, pageSize: number = 10) {  return db.select().from(users)    .limit(pageSize)    .offset(page * pageSize);}

Transactions

// Auto-rollback on errorawait db.transaction(async (tx) => {  await tx.insert(users).values({ email: '[email protected]', name: 'John' });  await tx.insert(posts).values({ title: 'First Post', authorId: 1 });  // If any query fails, entire transaction rolls back});// Manual controlconst tx = db.transaction(async (tx) => {  const user = await tx.insert(users).values({ ... }).returning();  if (!user) {    tx.rollback();    return;  }  await tx.insert(posts).values({ authorId: user.id });});

Migrations

Drizzle Kit Configuration

// drizzle.config.tsimport type { Config } from 'drizzle-kit';export default {  schema: './db/schema.ts',  out: './drizzle',  dialect: 'postgresql',  dbCredentials: {    url: process.env.DATABASE_URL!,  },} satisfies Config;

Migration Workflow

# Generate migrationnpx drizzle-kit generate# View SQLcat drizzle/0000_migration.sql# Apply migrationnpx drizzle-kit migrate# Introspect existing databasenpx drizzle-kit introspect# Drizzle Studio (database GUI)npx drizzle-kit studio

Example Migration

-- drizzle/0000_initial.sqlCREATE TABLE IF NOT EXISTS "users" (  "id" serial PRIMARY KEY NOT NULL,  "email" varchar(255) NOT NULL,  "name" text NOT NULL,  "created_at" timestamp DEFAULT now() NOT NULL,  CONSTRAINT "users_email_unique" UNIQUE("email"));

Navigation

Detailed References

  • 🏗️ Advanced Schemas - Custom types, composite keys, indexes, constraints, multi-tenant patterns. Load when designing complex database schemas.

  • 🔍 Query Patterns - Subqueries, CTEs, raw SQL, prepared statements, batch operations. Load when optimizing queries or handling complex filtering.

  • ⚡ Performance - Connection pooling, query optimization, N+1 prevention, prepared statements, edge runtime integration. Load when scaling or optimizing database performance.

  • 🔄 vs Prisma - Feature comparison, migration guide, when to choose Drizzle over Prisma. Load when evaluating ORMs or migrating from Prisma.

Red Flags

Stop and reconsider if:

  • Using any or unknown for JSON columns without type annotation
  • Building raw SQL strings without using sql template (SQL injection risk)
  • Not using transactions for multi-step data modifications
  • Fetching all rows without pagination in production queries
  • Missing indexes on foreign keys or frequently queried columns
  • Using select() without specifying columns for large tables

Performance Benefits vs Prisma

MetricDrizzlePrisma
Bundle Size~35KB~230KB
Cold Start~10ms~250ms
Query SpeedBaseline~2-3x slower
Memory~10MB~50MB
Type GenerationRuntime inferenceBuild-time generation

Integration

  • typescript-core: Type-safe schema inference with satisfies
  • nextjs-core: Server Actions, Route Handlers, Middleware integration
  • Database Migration: Safe schema evolution patterns

Related Skills

When using Drizzle, these skills enhance your workflow:

  • prisma: Alternative ORM comparison: Drizzle vs Prisma trade-offs
  • typescript: Advanced TypeScript patterns for type-safe queries
  • nextjs: Drizzle with Next.js Server Actions and API routes
  • sqlalchemy: SQLAlchemy patterns for Python developers learning Drizzle

[Full documentation available in these skills if deployed in your bundle]

Instalar drizzle-orm

Baixe e descompacte os arquivos de habilidades no diretório .claude/skills/.

Baixar ZIP

Clone o repositório e copie os arquivos da habilidade para o seu projeto.

git clone https://github.com/bobmatnyc/claude-mpm-skills/blob/main/toolchains/typescript/data/drizzle/SKILL.md # Copy SKILL.md to your .claude/skills/ directory

Copiar Copiar
Configuração rápida: Copie a pasta da habilidade para .claude/skills/. O Claude detectará e utilizará automaticamente a habilidade

Habilidades relacionadas

github-code-search
Tempo atualizado 29 de Junho de 2026
clickhouse-io
Tempo atualizado 29 de Junho de 2026
prisma-client-api
Tempo atualizado 29 de Junho de 2026
coding-standards
Tempo atualizado 29 de Junho de 2026
OR