Przejdź do treści

Drizzle vs Prisma: dlaczego używamy obu na produkcji

Dla CTO i programistówDecyzje CTO

Filip PapranecZałożyciel Digitaliko

Drizzle vs Prisma: jeden schemat, dwa ORM-y. Ilustracja: okno z schema.prisma obok okna z schema.ts i definicją sqliteTable, oba wskazują na plik migracji SQL.Drizzle vs Prisma: jeden schemat, dwa ORM-y. Ilustracja: okno z schema.prisma obok okna z schema.ts i definicją sqliteTable, oba wskazują na plik migracji SQL.

Drizzle vs Prisma to dla nas nie remis, ale też nie ma zwycięzcy. Używamy obu na produkcji: Prismy na Postgresie w starszych aplikacjach klientów i Drizzle na Cloudflare D1 w każdej nowej aplikacji, odkąd nową pracę przenieśliśmy na Workers. Krótka odpowiedź: Drizzle, gdy wdrażają Państwo na środowisko serverless lub edge i chcą mieć schemat i migracje jako czysty TypeScript i SQL; Prisma tam, gdzie już działa.

Większość porównań pisze jeden z dwóch dostawców albo ktoś, kto dwa razy zbudował demo. To porównanie pochodzi z repozytoriów, które utrzymujemy, z konfiguracją taką, jaka jest.

Drizzle vs Prisma: na czym polega prawdziwa różnica?

Oba dają typowanego klienta bazy danych w TypeScripcie. Różnica jest w tym, gdzie żyje schemat i jak daleko ORM jest od SQL.

PrismaDrizzle
Schematschema.prisma, własny językpliki .ts, czysty TypeScript
KlientGenerowany przez prisma generatePlik schematu jest typem, bez kroku generowania dla zapytań
ZapytaniaAPI obiektowe (findMany, include)W kształcie SQL (select().from().where()) plus API relacyjne
Migracjeprisma migrate dev / deploydrizzle-kit generate zapisuje pliki SQL, które Państwo stosują
Gdzie go używamyPostgres w starszych aplikacjach Next.jsCloudflare D1 (SQLite) w nowych aplikacjach
SilnikKlient bez Rusta od Prismy 7według dokumentacji „exactly 0 dependencies”

Dokumentacja Drizzle opisuje go jako „dialect-specific, slim, performant and serverless-ready by design” (Drizzle overview, sprawdzone 24.10.2026). Prisma to narzędzie wyższego poziomu: opisują Państwo modele, a ona decyduje o SQL.

Dlaczego nowe aplikacje działają na Drizzle?

Nasze nowe aplikacje działają na Cloudflare Workers z D1, czyli SQLite. Nasz szablon startowy i nasze wewnętrzne narzędzia mają ten sam układ. Cała konfiguracja Drizzle wygląda tak:

// packages/db/drizzle.config.ts
import { defineConfig } from 'drizzle-kit'

export default defineConfig({
  schema: './src/schema',
  out: './src/migrations',
  dialect: 'sqlite',
  driver: 'd1-http',
})

Schemat to plik TypeScript. Skrócony z naszego szablonu:

// packages/db/src/schema/records.ts
import { sql } from 'drizzle-orm'
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'
import { user } from './auth'

const record = sqliteTable('record', {
  id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),
  name: text('name').notNull(),
  status: text('status', { enum: ['active', 'inactive', 'pending'] }).default('active').notNull(),
  createdById: text('created_by_id').references(() => user.id, { onDelete: 'set null' }),
  createdAt: integer('created_at', { mode: 'timestamp_ms' })
    .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
    .notNull(),
})

Klient to jedna linia nad bindingiem D1, a zapytanie czyta się jak SQL:

import { drizzle } from 'drizzle-orm/d1'
import * as schema from './schema'

const createDb = () => drizzle(env.DB, { schema })

const [total] = await ctx.db.select({ count: count() }).from(record)

Trzy powody sprawiły, że przy nowej pracy zmieniliśmy ORM:

  • Środowisko uruchomieniowe. Celem były D1 i Workers. Drizzle łączy się przez import { drizzle } from 'drizzle-orm/d1' (Drizzle i D1).
  • Agent czyta schemat bezpośrednio. Większość naszego kodu pisze AI, a za produkcję odpowiada senior. Schemat w TypeScripcie to po prostu kod: agent go edytuje, sprawdzanie typów od razu wyłapie złą kolumnę i nie ma wygenerowanego klienta, o którego regeneracji można zapomnieć.
  • Migracje to SQL w PR. Reviewer widzi dokładne ALTER TABLE, a nie diff pliku modelu.

Uwierzytelnianie korzysta z tej samej bazy danych. Better Auth podłącza się przez drizzleAdapter(db, { provider: 'sqlite' }), więc użytkownicy i sesje to zwykłe tabele obok tabel samej aplikacji.

Drizzle vs Prisma obok siebie. Po lewej Prisma w starszych aplikacjach: schema.prisma, prisma generate, prisma migrate deploy w buildzie, Postgres. Po prawej Drizzle w nowych aplikacjach: schema.ts w TypeScripcie, drizzle-kit generate zapisuje plik SQL, a wdrożenie stosuje go na Cloudflare D1. Stopka: nowe aplikacje na Drizzle, działające aplikacje na Prismie zostają.Drizzle vs Prisma obok siebie. Po lewej Prisma w starszych aplikacjach: schema.prisma, prisma generate, prisma migrate deploy w buildzie, Postgres. Po prawej Drizzle w nowych aplikacjach: schema.ts w TypeScripcie, drizzle-kit generate zapisuje plik SQL, a wdrożenie stosuje go na Cloudflare D1. Stopka: nowe aplikacje na Drizzle, działające aplikacje na Prismie zostają.

Jak zmiana schematu trafia na produkcję?

Zmiana idzie tą samą drogą w każdej nowej aplikacji. Nikt nie uruchamia ręcznie SQL na produkcji.

  1. Zmienić schemat w TypeScripcie

    Dodać kolumnę lub tabelę w packages/db/src/schema. Sprawdzanie typów oznaczy każde zapytanie, które już nie pasuje.

  2. Wygenerować migrację

    drizzle-kit generate zapisuje ponumerowany plik SQL w packages/db/src/migrations.

  3. Przejrzeć SQL w PR

    Zmiana schematu i plik SQL idą razem, więc reviewer czyta prawdziwe polecenie.

  4. Wdrożenie stosuje ją na D1

    Nasz kod infrastruktury kieruje D1 na folder migracji i przy wdrożeniu stosuje nowe pliki.

Część wdrożeniowa jest w naszym kodzie infrastruktury, napisanym w TypeScripcie z Alchemy:

// packages/infra/alchemy.run.ts (skrócone)
const db = await D1Database('database', {
  migrationsDir: '../../packages/db/src/migrations',
})

const web = await TanStackStart('web', {
  cwd: '../../apps/web',
  bindings: { DB: db },
})

Jeden folder plików SQL to historia bazy danych. Właśnie to sprawia, że przekazanie projektu jest czytelne dla kolejnego inżyniera.

Gdzie Prisma wciąż wygrywa i dlaczego ją zostawiamy?

Kilka starszych aplikacji klientów działa na Prismie i Postgresie, w kilku głównych wersjach Prismy. Jedna z nich to system, który zbudowaliśmy i utrzymujemy dla firmy spedycyjnej. Większość używa klasycznego układu: prisma-client-js, NextAuth z adapterem Prismy i prisma migrate deploy w skrypcie buildu, więc każde wdrożenie aktualizuje bazę danych przed next build.

Ten układ działa. Język modeli Prismy łatwo czyta ktoś, kto nie pisze SQL na co dzień, a jej przepływ migracji jest dojrzały. Nie widzimy powodu, żeby usuwać ją z aplikacji, która dobrze służy użytkownikom.

Zmiana ORM-a dotyka naraz każdego zapytania, każdego testu i każdej migracji, a użytkownik nie widzi nic nowego. To ryzyko opłaca się tylko wtedy, gdy wymusza je coś innego, na przykład przejście na Workers. Gdy przejmujemy starszą aplikację, jej ORM rzadko jest pierwszą rzeczą wartą naprawy. Jak wybieramy, co idzie najpierw, opisujemy w artykule Dług techniczny: jak go mierzyć i co naprawić najpierw?.

Jeszcze jedna uczciwa uwaga: internetowy marketplace jednego klienta działa na MongoDB z Mongoose, więc tam nie ma żadnego z tych ORM-ów.

Co zmieniła Prisma 7?

Wiele tekstów „Drizzle vs Prisma” wciąż spiera się o binarny silnik w Rust. Ten argument jest dziś słabszy. Prisma ORM 7 ukazała się 19 listopada 2025 z „Rust-free Prisma Client as the default” (Prisma changelog, sprawdzone 24.10.2026). Przewodnik aktualizacji mówi:

Upgrade to the new prisma-client provider which uses the new Rust-free client.

Dokumentacja Prismy
Aktualizacja do Prisma ORM 7 (sprawdzone 24.10.2026)

Ten sam przewodnik mówi, że driver adapter jest teraz wymagany dla każdej bazy danych. Prisma 7 działa więc także na Workers, a na D1 przez @prisma/adapter-d1. Strona Prismy o D1 dodaje ostrzeżenie, które dotyczy każdego ORM-a: D1 nie obsługuje transakcji, więc „implicit & explicit transactions will be ignored and run as individual queries” (Prisma i Cloudflare D1, sprawdzone 24.10.2026).

Szczerze: nie robiliśmy benchmarku Drizzle kontra Prisma 7 i nie uruchamialiśmy Prismy 7 na D1. Większość naszych aplikacji na Prismie wciąż używa prisma-client-js; najnowsza działa już na nowym generatorze prisma-client. Jeśli porównują Państwo oba dziś, proszę porównywać z Prismą 7, a nie z wersją ze starych wpisów na blogach.

Drizzle czy Prisma w następnej aplikacji?

Proszę przejść przez punkty. Im więcej z nich się zgadza, tym lepiej pasuje Drizzle:

Niezależnie od wyboru, migracje warto trzymać w repozytorium i stosować przy wdrożeniu, nigdy ręcznie. Jeśli i tak rozważają Państwo przepisanie, najpierw warto przeczytać Refaktoryzacja czy przepisanie od zera? Jak zdecydować.

Chcą Państwo aplikacji webowej z warstwą danych czytelną dla kolejnego inżyniera?

Budujemy aplikacje webowe na tym stacku, przy nowej pracy Drizzle na D1, a aplikacje na Prismie przejmujemy bez przepisywania tego, co działa: aplikacje webowe na zamówienie. Większość naszego kodu pisze AI. Senior sprawdza każdą zmianę i odpowiada za produkcję. Od 2023 roku dostarczyliśmy ponad 15 projektów produkcyjnych.

Odezwiemy się w ciągu dwóch dni roboczych z kilkoma pytaniami o Państwa pracę. Potem ustalimy, co zrobimy najpierw.

Jeśli wolą Państwo najpierw porozmawiać, proszę zarezerwować 15-minutową rozmowę wstępną.

O który ORM spiera się teraz Państwa zespół?

W skrócie

  • Używamy obu: Prismy na Postgresie w starszych aplikacjach, Drizzle na Cloudflare D1 w każdej nowej.
  • Drizzle trzyma schemat w TypeScripcie, a migracje jako pliki SQL, które przechodzą review.
  • Prisma 7 porzuciła silnik w Rust, więc stary argument o binarce już nie rozstrzyga.
  • Nigdy nie przepisujemy działającej aplikacji na Prismie tylko po to, żeby zmienić ORM.

Najczęstsze pytania

Czy Drizzle jest lepszy niż Prisma?

Żaden nie jest lepszy ogólnie. Drizzle pasuje do środowisk serverless i edge, takich jak Cloudflare Workers z D1, trzyma schemat w czystym TypeScripcie i zostaje blisko SQL. Prisma pasuje do zespołów, które chcą klienta wyższego poziomu, własnego przepływu migracji i narzędzi takich jak Prisma Studio, zwykle na Postgresie.

Czy Prisma wciąż potrzebuje binarnego silnika w Rust?

Nie od Prisma ORM 7, wydanej 19 listopada 2025. Nowy generator prisma-client używa klienta bez Rusta i wymaga driver adaptera dla każdej bazy danych. Aplikacje, które zostały przy prisma-client-js na Prismie 5 lub 6, domyślnie używają silnika w Rust.

Czy Prisma działa na Cloudflare D1?

Tak, przez driver adapter @prisma/adapter-d1. Dokumentacja Prismy ostrzega, że D1 nie obsługuje transakcji, więc transakcje niejawne i jawne wykonują się jako pojedyncze zapytania. To samo ograniczenie D1 dotyczy każdego ORM-a.

Czy warto migrować istniejącą aplikację z Prismy na Drizzle?

Zwykle nie. Przepisanie warstwy danych w działającej aplikacji niesie realne ryzyko i nie daje użytkownikom niczego nowego. Na Drizzle przechodzimy, gdy zaczynamy nową aplikację albo gdy zmienia się środowisko uruchomieniowe, na przykład na Cloudflare Workers.

Jak działają migracje w Drizzle?

Zmieniają Państwo schemat w TypeScripcie, drizzle-kit generate zapisuje czysty plik migracji SQL, a ten plik jest stosowany przy wdrożeniu. W naszych aplikacjach plik SQL przechodzi code review w tym samym PR co zmiana schematu.

Zapytaj AI o ten artykuł

AI przy odpowiedzi wykorzysta też nasze inne artykuły i doświadczenia z prawdziwych projektów.

ChatGPTClaudePerplexity
Engineering

Kolejne artykuły

Decyzje CTO

Refaktoryzacja czy przepisanie od zera? Jak zdecydować

Refaktoryzacja, gdy kod robi właściwą rzecz źle. Przepisanie, gdy robi niewłaściwą rzecz albo kod nie należy do Państwa. Tabela decyzyjna dla CTO i sposób, by zrobić to bez zatrzymywania roadmapy.

Decyzje CTO

Dług techniczny: jak go mierzyć i co naprawić najpierw?

Dług techniczny zmierzą Państwo na podstawie historii git i błędów, bez drogiego narzędzia. Najpierw warto naprawić kod, który zmienia się najczęściej i blokuje roadmapę, a nie ten najbrzydszy. Poradnik dla CTO.

Decyzje CTO

Body leasing czy senior w zespole? Jak wybrać

Body leasing daje godziny programisty, którymi zarządzają Państwo sami. Senior w zespole daje zrealizowane zadania i zespół, który uczy się pracy z AI. Porównanie z outsourcingiem i rekrutacją, dla CTO.