Skip to content

Database ORM Selection

Date: 2026-01-14

Status: accepted

Context

We are building a user enrichment database to store data collected during onboarding and personalization flows.

We need an ORM that provides:

  • TypeScript support: Strong typing without manual code generation steps
  • Good Performance: Suitable for lambdas
  • Team familiarity: Easy to learn and maintain
  • Ecosystem: Good community support, documentation, and maintenance
  • Good migration tooling: Easy modification of fields as requirements evolve

We checked both Prisma and Drizzle as the primary candidates before deciding.

Decision

We will use Drizzle ORM as our database layer.

Key factors in our decision:

  • SQL transparency: Drizzle's query syntax mirrors SQL directly, helping us learn and understand SQL rather than learning ORM-specific abstractions. This also makes it easier to collaborate across teams.
  • Lightweight for Lambda: The bundle size (~50KB) is significantly smaller than Prisma, reducing cold start times in our serverless environment.
  • Instant type safety: Types are inferred directly from schema definitions without a generation step. The types stay in sync with the code automatically.
  • Readable migrations: drizzle-kit generates SQL migration files that we can read and review, providing transparency into database changes.
  • Schema definitions in TypeScript: Schemas are defined as TypeScript code, serving as the single source of truth without additional schema languages.

Consequences

The migration workflow requires some manual input - developers have to run pnpm run db:generate after schema changes and pnpm run db:migrate to apply them.

Drizzle has a smaller ecosystem compared to Prisma, which may mean fewer community resources and third-party integrations. The learning curve requires understanding SQL concepts rather than ORM abstractions, which is a trade-off we accept for better long-term maintainability and transparency.