Prisma vs Drizzle vs Kysely: TypeScript Veri Katmanı Seçimi
Postgres üzerinde TypeScript veri katmanı için karar çerçevesi: SQL'in ne kadarı kütüphanede kalmalı, Lambda'da maliyeti ne, varsayılan ne zaman yanlış.
Postgres üzerinde kurulan her yeni TypeScript servisi, geri dönüşü pahalı olan tek bir kararı dayatır: SQL’in ne kadarını bir kütüphaneye devrediyorsunuz? Prisma, Drizzle ve Kysely bu soruya farklı cevap verir ve fark bir özellik listesi değildir. Fark, tiplerin nereden geldiği ve sorguyu kimin yazdığıdır. Lambda üzerinde çalışan, Postgres tabanlı yeni bir servis için varsayılan Drizzle. Şemanın ve migration’ların sahipliğini üstlenir, ama sorgunun şeklini yine de kod içinde görünür bırakır. Bu varsayılanı geçersiz kılan iki koşul var. Prisma’ya yöneltilen ve karşılaştırmaların çoğunda hâlâ tekrarlanan serverless itirazı da geçerliliğini yitirdi; yerine geçen daha dar itirazı fark etmek ise çok daha zor.
Burada Postgres’in zaten seçilmiş olduğu varsayılıyor. O karar hâlâ açıksa, Veritabanı nasıl seçilir bir alttaki katmanı ele alıyor; ilişkisel bir deponun hiç uygun olmadığı durum için de DynamoDB tek tablo tasarımı rehberi var.
Aşağıdaki sürüm numaraları 3 Ağustos 2026’da doğrulandı. Bu numaralar etraflarındaki argümanlardan çok daha hızlı değişiyor, dolayısıyla bir sürümü sabitlemeden önce yeniden kontrol edin.
Eksen: SQL’in sahibi kim#
Herhangi bir veri katmanı aracını tek bir doğru üzerine yerleştirdiğinizde karşılaştırma epey kısalır. Doğrunun bir ucunda SQL’i siz yazarsınız, TypeScript de onu denetler. Diğer ucunda bir şema tarif edersiniz, hangi SQL’in çalışacağına kütüphane karar verir. Bu üç araç, o doğru üzerinde birbirinden ayrı üç noktada durur.
Kysely tip güvenli bir sorgu kurucusudur ve bunu açıkça söyler: ORM değildir, ilişki (relation) kavramı yoktur. Kurucu SQL grameriyle aynı biçimi izlediği için sorgu da SQL gibi okunur. Tipler, elle bakımını yaptığınız ya da kysely-codegen ile canlı veritabanından ürettiğiniz bir Database arayüzünden gelir. Node.js’in yanında Deno, Bun, Cloudflare Workers ve tarayıcılarda da çalışır; PostgreSQL, MySQL, MSSQL, SQLite ve PGlite dialektlerini destekler.
Drizzle SQL öncelikli bir yaklaşımdır. Şemayı TypeScript içinde tanımlarsınız, temel tipler ayrı bir codegen adımı olmadan bu şema nesnelerinden çıkarılır ve sorgu API’si SQL’e yakın durur.
Prisma SQL’in sahipliğini üstlenir. Şemayı kendine özgü bir DSL içinde tanımlarsınız, bir generator client üretir ve hangi SQL’in çalışacağına o client karar verir. Karşılığında nesne grafiği gibi okunan ilişkisel bir API alırsınız.
Tek bir sorgu farkı somutlaştırıyor: yayımlanmış en yeni on gönderi ve her birinin yazar adı.
// Kysely: join'i siz yazarsınız, tipleri kysely-codegen üretir
import { Kysely, PostgresDialect } from "kysely";
import pg from "pg";
import type { DB } from "./types/db.js";
const db = new Kysely<DB>({
dialect: new PostgresDialect({
pool: new pg.Pool({ connectionString: process.env.DATABASE_URL }),
}),
});
const rows = await db
.selectFrom("post")
.innerJoin("author", "author.id", "post.author_id")
.select(["post.id", "post.title", "author.name as author_name"])
.where("post.published", "=", true)
.orderBy("post.created_at", "desc")
.limit(10)
.execute();
// Drizzle: tiplerin kaynağı TypeScript şeması, ayrı bir codegen adımı yok
import { drizzle } from "drizzle-orm/node-postgres";
import { desc, eq } from "drizzle-orm";
import { author, post } from "./schema.js";
const db = drizzle(process.env.DATABASE_URL!);
const rows = await db
.select({ id: post.id, title: post.title, authorName: author.name })
.from(post)
.innerJoin(author, eq(author.id, post.authorId))
.where(eq(post.published, true))
.orderBy(desc(post.createdAt))
.limit(10);
// Prisma 7: üretilen client node_modules içinde değil, açık bir output yolunda durur
import { PrismaClient } from "./generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
const rows = await prisma.post.findMany({
where: { published: true },
select: { id: true, title: true, author: { select: { name: true } } },
orderBy: { createdAt: "desc" },
take: 10,
});
Söz dizimine değil, dönen sonucun şekline bakın. Kysely ve Drizzle, join’i siz yazdığınız için author_name alanını taşıyan düz bir satır döndürür. Prisma ise iç içe geçmiş bir nesne döndürür, çünkü ilişkinin nasıl çekileceğine client karar vermiştir. Takas tek cümlede budur: çağrı noktasında kolaylık, karşılığında sizin belirlemediğiniz ve soyutlamadan çıkmadan değiştiremeyeceğiniz bir join stratejisi.
Bu doğru üzerindeki konumlar sabit de değil. Drizzle’ın Relational Queries v2 sürümü nesne grafiği okumasını zenginleştiriyor. Prisma kendi yazısında bunun, 2020’de kendisinin getirdiği kalıplara doğru bir yakınsama olduğunu savunuyor; gerekçe olarak da Drizzle’ın test setinin 600’den 9.000’in üzerine çıkmasını gösteriyor. Bu, bir üreticinin rakibi hakkında yazdığı bir metin, dolayısıyla bulgu değil iddia olarak tartın. Asıl akılda kalması gereken, argümanın dışarıda bıraktığı şey: Kysely bu tabloda hiç yok, çünkü doğrunun sorgu kurucusu ucu hiçbir şeye yakınsamıyor.
Neden varsayılan Drizzle#
Üç araç içinde problemin iki yarısını birden çözen tek seçenek Drizzle. Şemanın ve migration sürecinin sahipliğini üstleniyor, yani veri katmanını birbiriyle ilgisiz üç ayrı araçtan kurmuyorsunuz. Aynı zamanda sorgunun şeklini kod içinde görünür bırakıyor, yani okuduğunuz SQL çalışan SQL’e yakın duruyor. Hem birinci gündeki cold start bütçesine hem de altı ay sonraki performans incelemesine dayanabilen bileşim bu. drizzle-kit generate çalışmadan önce bir insanın okuyabileceği SQL dosyaları üretiyor, şema servisin geri kalanıyla aynı dilde duruyor ve artifact içinde bir engine binary’si bulunmuyor.
Sürüm durumu ise eski karşılaştırmaların atladığı kısım; varsayılana bırakılacak değil, karar verilecek bir konu. npm üzerinde drizzle-orm latest etiketi 0.45.2’yi, drizzle-kit latest etiketi 0.31.10’u gösteriyor; ikisi de hâlâ 0.x. Buna karşılık beta etiketi 1.0.0-beta.22’de, rc etiketi ise 27 Haziran 2026’da yayımlanan 1.0.0-rc.4’te. Yani Drizzle v1 beta’dan release candidate aşamasına geçti ama latest etiketini almadı. Yayımlanmış karşılaştırmaların çoğu v1’i hâlâ beta olarak anlatıyor; bu birkaç ay öncesine kadar doğruydu.
Aradaki bu boşluk pratik bir tuzak yaratıyor. v0’dan v1’e geçiş dokümantasyonu v1 güncel sürümmüş gibi okunuyor, oysa npm install drizzle-orm komutunu çalıştıran okuyucunun eline 0.45.2 geçiyor. İki okuyucu farklı kütüphaneler ve farklı API’lerle kalıyor. v0’dan v1’e değişiklikleri ilk şema dosyasını yazmadan önce okuyun, sonra değil. Relational Queries v1 genişletilmedi, kaldırıldı; listenin geri kalanı da aynı sertlikte. v2 yeni bir defineRelations() API’si getiriyor, doğrulama entegrasyonları drizzle-zod, drizzle-valibot ve drizzle-typebox paketlerinden drizzle-orm/zod ve kardeşlerine taşınıyor, drizzle-orm/effect-schema ekleniyor, migration klasörü journal.json dosyasını bırakan v3 biçimine geçiyor ve drizzle-kit drop komutu kaldırılıyor.
Dolayısıyla buradaki takas benimseme zamanlamasıyla ilgili. Büyük bir sürüm geçişinin ortasındaki bir kütüphaneyi alıyorsunuz ve hata modu, başkasının takvimine göre zorunlu hâle gelen bir migration. 0.45.2 ile başlamak ileride Relational Queries v1’den v2’ye geçişi kabul etmek demek. Release candidate ile başlamak ise stabil öncesi çalkantıyı kabul etmek demek. Hangisi olursa olsun belirli bir sürümü sabitleyin: package.json içine caret ya da tilde aralığı değil, tam sürüm numarası yazın ve gerekçesini depoya not edin. Böylece sizden sonrakine bir lock dosyası değil, bir karar kalır.
Birleştirilen doğrulama paketleriyle ilgili küçük bir not: pratik olmalarına rağmen iki tip sistemini zihninizde ayrı tutun. API sınırında kabul ettiğiniz şekil ile sakladığınız şekil ilişkilidir, aynı değildir. Zod ve OpenAPI ile şema öncelikli API geliştirme istek tarafını kendi başına bir sözleşme olarak ele alıyor; doğru refleks de bu.
Prisma 7 ve paket boyutu itirazı#
Lambda üzerinde Prisma’ya yöneltilen refleks itiraz eskiden Rust engine binary’siydi. O itiraz 19 Kasım 2025’te geçerliliğini yitirdi. O gün Prisma 7.0.0 yayımlandı, Rust içermeyen client varsayılan hâle geldi ve prisma-client-js generator’ının yerini prisma-client provider’ı aldı. Paketleme açısından belirleyici olan gerçek şu: artık gönderilecek platforma özgü bir native binary yok. Prisma bunu TypeScript’e yeniden yazım olarak anlatıyor, üçüncü taraf yazılar ise sorgu derleyicisinin JavaScript thread’i üzerinde bir WebAssembly modülü olarak çalıştığını söylüyor. Bir Lambda artifact’i açısından bu iki tarif arasındaki fark hiçbir şeyi değiştirmez; native binary’nin yokluğu ise çok şeyi değiştirir.
Prisma’nın kendi benchmark yazısı paket boyutunu öncesinde yaklaşık 14 MB, sonrasında 1,6 MB olarak veriyor; ölçüm PostgreSQL üzerinde pg sürücüsüyle yapılmış. Bunlar üreticinin kendi benchmark’ından çıkan üretici rakamları, dolayısıyla garanti değil yön olarak okuyun. Yön zaten ciddi biçimde tartışmalı değil: derlenmiş bir engine taşımayan artifact başka bir artifact’tir. Kendi ölçümünüzü Lambda’ya giden zip üzerinde yapın; zip ile node_modules sayıları düzenli olarak birbirini tutmaz. Nedenini AWS Lambda TypeScript anti-pattern’leri anlatıyor.
Yükseltmenin bedeli mimari değil operasyonel ve takılması kolay. Sürüm 7’de üretilen client node_modules dışına çıktı ve artık schema.prisma içinde açık bir output yolu istiyor. Yani @prisma/client yerine üretilen dizinden import ediyorsunuz. Post-install hook kaldırıldı, dolayısıyla prisma generate komutunun açıkça çağrılması gerekiyor. Örtük hook’a güvenen Docker build’leri ve CI pipeline’ları kırılacak, hata mesajı da bu iki değişikliğin hiçbirini doğrudan işaret etmeyecek. Driver adapter’lar artık kaynak kodda açıkça veriliyor; yapılandırma ise prisma.config.ts dosyasına taşındı ve bu dosya introspection ile CLI veritabanı iş akışları için zorunlu.
Performans tarafında dürüst bir dipnot da var ve kaynağı Prisma’nın kendisi. 7.0 duyurusu 3 kat daha hızlı sorgu çalıştırma ve %90 daha küçük paket çıktısı iddialarıyla açılıyor. Üç ay sonra yayımlanan AMA yazısı ise şunu kabul ediyor: “There are also cases where throughput is similar or slightly worse”, yani bazı senaryolarda verim benzer ya da bir miktar daha düşük kalıyor. Gerekçe mimari: sürüm 7 veritabanıyla ayrı ve çok thread’li bir Rust çalışma zamanı üzerinden değil, doğrudan JavaScript’ten konuşuyor. Buradan çıkarılacak yararlı sonuç, iki sayı grubunun aynı anda doğru olabildiği: tepe paralellik bilinçli olarak serverless ve edge uyumuyla takas edilmiş. Lambda üzerinde de takasın olmak isteyeceğiniz tarafı burası.
Lambda üzerinde bağlantı havuzu#
Paket boyutu birinci günün sayısıdır. Üretimde asıl sıkıştıran kısıt bağlantılardır. Postgres katı bir max_connections sınırı uygular, Lambda ise kimseye sormadan yatay ölçeklenir. Veri katmanı seçimi de hangi havuzlama mimarisinin size açık kaldığını sessizce belirler.
Temel yönlendirme üç araç için de aynı ve Prisma bunu net biçimde belgeliyor. Client’ı handler dışında oluşturun ki sıcak çağrılar arasında yaşasın. İstek sonunda bağlantıyı kapatmayın, çünkü yeni bağlantı açmak zaman alır ve sonraki her çağrıda fonksiyonu yavaşlatır. Ardından reserved concurrency değerini, veritabanının bağlantı sınırının her fonksiyonun tuttuğu bağlantı sayısına bölümünden küçük tutun. Aşağıdaki örnekte havuz boyutu 1, yani eşzamanlı çalışan her fonksiyon tek bir bağlantı tutuyor. Havuzu büyütürseniz aynı eşzamanlılıkta veritabanından bunun katı kadar bağlantı istemiş olursunuz.
// handler.ts: havuz handler dışında yaşar, sıcak çağrılar onu yeniden kullanır
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import { post } from "./schema.js";
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
// bir çalıştırma ortamı aynı anda tek bir isteğe hizmet eder;
// bunu yalnızca tek bir handler paralel sorgu açıyorsa artırın
max: 1,
});
const db = drizzle(pool);
export const handler = async () => {
const rows = await db.select().from(post).limit(10);
return { statusCode: 200, body: JSON.stringify(rows) };
};
Üç aracın birbirinin yerine geçmeyi bıraktığı nokta, AWS’ye özgü şu ayrıntı. Standart serverless tavsiyesi Postgres’in önüne RDS Proxy koymaktır ve çoğu client için bu tavsiye geçerlidir. Prisma’nın dağıtım dokümantasyonu daha dar ve daha kesin bir şey söylüyor. Prisma ORM, RDS Proxy ile uyumludur, ancak bağlantı havuzlaması için kullanmanın bir faydası yoktur. Herhangi bir boyuttaki prepared statement, RDS Proxy’nin oturumu tek bir bağlantıya sabitlemesine (session pinning) yol açar ve Prisma her sorguda prepared statement kullanır. Sabitlenmiş bir oturum, paylaşılmayan bir oturumdur; proxy’nin varlık nedeni de tam olarak o paylaşımdı.
Tetikleyici prepared statement’ın kendisi ve bunu gönderen tek client Prisma değil. postgres.js da varsayılan olarak prepared statement kullanır ve aynı şekilde sabitlemeye yol açar; pg ise statement’a isim vererek açıkça devreye almanızı ister. Dolayısıyla tasarım aşamasında sorulacak asıl soru hangi havuzlama mimarisine bağlandığınız; kütüphane hızı ondan sonra gelir. RDS Proxy tasarımınızda taşıyıcı bir rol oynuyorsa, üzerine inşa etmeden önce client’ın prepared statement davranışını doğrulayın. Oynamıyorsa, transaction modunda PgBouncer ya da serverless’a uygun bir Postgres kısıtı ortadan kaldırır: Aurora Serverless v2 nasıl çalışır ve Aurora ile RDS arasındaki takaslar kararın o tarafını ele alıyor.
Şema sahipliği ve migration’lar#
Prisma ve Drizzle, migration’ları sizin tanımladığınız bir şemadan üretir. Kysely yönü tersine çevirir: doğruluğun kaynağı veritabanıdır ve tipler oradan üretilir. İki yön de bedelsiz değil ve ekiplerin değerlendirme aşamasında en sık atladığı bölüm burası.
Prisma şema DSL’ini prisma migrate ile, onun dev ve deploy ayrımıyla birlikte kullanır. Drizzle, TypeScript şemasını drizzle-kit generate ve drizzle-kit migrate ile birlikte kullanır ve çalışmadan önce okuyup düzenleyebileceğiniz SQL dosyaları üretir. Kysely’nin ise hiç şeması yoktur. Migrator bileşeni elle yazılmış up ve down fonksiyonlarını alfanümerik sırayla, veritabanı seviyesinde kilitleyerek çalıştırır; böylece bir migration yalnızca bir kez yürütülür. Paralel dallarda migration ekleyen ekipler için allowUnorderedMigrations seçeneği vardır. Hiçbir şey bir şemadan üretilmez. kysely-ctl CLI’ı ise isteğe bağlıdır ve projenin kendi ifadesiyle çekirdeğin parçası değildir. Bu yüzden Kysely kullanan çoğu ekip yanına, DATABASE_URL değişkenini okuyup Database arayüzünü üreten kysely-codegen aracını koyar.
Hata modları simetrik. Şema tanımlayan bir araç, DSL’inin modellemediği bir değişikliği ifade edemeyebilir; o noktada üretilmiş bir migration’ın içine zaten elle SQL yazarsınız. Veritabanı öncelikli bir araçta ise biri codegen’i yeniden çalıştırmayı unuttuğu anda kayma başlar ve tip sistemi her şeyin yolunda olduğunu kendinden emin biçimde bildirir. Kysely özelinde çözüm kysely-codegen aracını CI içinde çalıştırıp fark çıktığında build’i kırmaktır; bu, sessiz bir kaymayı kırmızı bir pipeline’a çevirir.
Ham SQL’e çıkış kapıları#
Üçünde de var. Fark, o kapıdan çıkarken neyi geride bıraktığınızda. Kysely’nin sql şablonu kurucuyla doğal biçimde birleşir, çünkü kurucu zaten SQL biçimindedir. Drizzle’ın sql şablonu benzer davranır. Prisma’nın $queryRaw fonksiyonu client’ın modelinin dışına çıkar; dönüş tipini elle belirtmediğiniz sürece client’ın sonuç tiplemesinin de dışına çıkmış olursunuz. TypedSQL bu boşluğu SQL dosyalarını şemaya karşı tip denetiminden geçirerek daraltıyor.
Görünür SQL argümanı asıl değerini ilk kurulum sırasında değil, bir inceleme sırasında gösterir. Sıcak bir endpoint yavaşladığında, okuduğunuz kod ile veritabanının çalıştırdığı SQL arasındaki mesafe, hata ayıklama döngünüzün uzunluğudur. Sistematik sorgu profilleme çalışması, kaynaktaki sorgu ile plandaki sorgu aynı olduğunda çok daha kısa sürer.
Karar akışı#
Aşağıdaki ağaç nötr biçimde dallanmıyor, varsayılanın üzerine kuruluyor. Her dal bir geçersiz kılma koşulu ve her biri ekibiniz ile veritabanınız hakkında bir ifade; kütüphane kalitesinin burada payı yok. İki sorunun sırası da bilinçli. Şema sahipliği, ikisi arasında altı ay içinde değiştirilmesi en zor olanı; ekibin SQL alışkanlığı ise zamanla değişebilir. Bu yüzden sahiplik sorusu önce geliyor.
Aynı üç konum, tartışmayı genelde belirleyen boyutlara karşı:
| Boyut | Kysely 0.29.4 | Drizzle 0.45.2 / 1.0.0-rc.4 | Prisma 7.9.1 |
|---|---|---|---|
| Kategori | Sorgu kurucusu, ORM değil | SQL öncelikli ORM | ORM, SQL’in sahibi client |
| Tip kaynağı | Database arayüzü, canlı veritabanından kysely-codegen ile üretilir | TypeScript şemasından çıkarım | DSL’den üretilen client |
| Şema sahipliği | Yok, doğruluğun kaynağı veritabanı | TypeScript şema dosyaları | schema.prisma DSL’i |
| Migration | Elle yazılan up ve down, kysely-ctl isteğe bağlı ve çekirdek dışı | drizzle-kit generate, incelenebilir SQL dosyaları | prisma migrate |
| İlişkiler | İlişki kavramı yok | Relational Queries v2, defineRelations() | İlişkisel API, kalıbın ilk örneği |
| Üretilen SQL | Siz yazdınız | Yazdığınıza yakın | Kütüphanenin kararı |
| Çıkış kapısı | sql şablonu, doğal biçimde birleşir | sql şablonu | $queryRaw ve TypedSQL |
| Çalışma zamanı bağımlılıkları | Yok | Yalnızca sürücü | Driver adapter, v7’den beri native binary yok |
| Kararlılık | 0.x, istikrarlı | latest etiketinde 0.x, v1 release candidate | Kararlı ana sürüm, 7.x |
| Lisans | MIT | Apache-2.0 (drizzle-orm), MIT (drizzle-kit) | Apache-2.0 |
Varsayılanı ne zaman değiştirmeli#
Birinci durum: ekip akıcı biçimde SQL yazmıyor ve şema, alan modelinin kendisi. Prisma kullanın. Zihinsel model nesne grafiğiyse ilişkisel API gerçekten daha hızlı ilerletir ve Lambda üzerinde onu eskiden eleyen itiraz artık geçerli değil. Yine de bağlanmadan önce havuzlama tarafına bakın. Mimariniz RDS Proxy varsayıyorsa, Prisma’nın kendi dokümantasyonu ondan bir havuzlama faydası görmeyeceğinizi söylüyor. O hâlde PgBouncer tarzı bir havuzlama ya da serverless’a uygun bir Postgres planlayın.
Kabul ettiğiniz takas, hız karşılığında sorgu kontrolü. Hata modu tek bir endpoint olarak gelir: üretilen SQL’ini soyutlamanın dışına çıkmadan değiştiremezsiniz ve o noktaya geldiğinizde soyutlama kod tabanının her yerinde taşıyıcı hâle gelmiştir. AWS üzerinde ikinci hata modu, proxy sabitleme davranışını havuzlama mimarisi kurulup dağıtıldıktan sonra fark etmektir.
İkinci durum: veritabanı eski, paylaşılan ya da başka bir ekibin mülkü; ya da amacınız olabilecek en küçük bağımlılık yüzeyi. Kysely’yi kysely-codegen ile kullanın ve migration aracını ayrıca seçin. Şemanın sahibi siz değilseniz tipleri canlı veritabanından üretmek doğru yöndür ve üç araç içinde bu yön için tasarlanmış tek seçenek Kysely. npm kaydında yalnızca devDependencies listeleniyor, yani çalışma zamanı bağımlılığı taşımıyor; Lambda paketi için elde edilebilecek en temiz durum bu.
Şema kayması ve migration araçları burada sizin işiniz olur. Bu bedel çoğunlukla şöyle gelir: üç dağıtım önce üretimle örtüşmeyi bırakmış bir Database arayüzü, o süre boyunca da başarı bildiren bir tip denetleyicisi. İkincil risk bakım yoğunlaşması: Kysely yaklaşık 14,1 bin GitHub yıldızına sahip, arkasında projeyi sürdüren küçük bir ekip var ve görünür bir kurumsal sponsoru yok. Bunu değerlendirme aşamasında yüksek sesle sorun; soru iki yönlü de çalışıyor, çünkü küçük bir bağımlılık yüzeyi aynı zamanda fork’lanması küçük bir şey demek.
Neden TypeORM veya Sequelize değil#
Bu bölümün tembel hâli, ikisinin de eski olduğunu söylemek; TypeORM için bu artık yanlış. TypeORM, 19 Mayıs 2026’da projenin 2016’daki başlangıcından bu yana ilk ana sürümü olan 1.0.0’ı yayımladı; ardından 13 Temmuz 2026’da 1.1.0 geldi ve 0.3.x dalı bakım almaya devam ediyor. Canlanma sayılarla ortada. 2024 sonunda projeyi yeni bir ekip devraldı. 2025 boyunca proje 8 yama sürümü yayımladı, birleştirilen pull request sayısını bir önceki yılki 63’ten 575’e çıkardı ve 2.300’den fazla issue kapattı; haftalık indirme sayısı da yaklaşık 2 milyon. Sürüm 1.0 ayrıca yığını modernleştirdi: asgari Node.js 20, mysql yerine mysql2, sqlite3 yerine better-sqlite3, hash için native crypto ve tüm sürücülerde parametreli sorgular.
Dolayısıyla TypeORM’a yöneltilecek dürüst itiraz artık tasarımıyla ilgili. Araç decorator tabanlı ve entity merkezli; sizinle SQL arasına bir sınıf hiyerarşisi koyuyor. Tip güvenliğinin geri kalanının çıkarımdan geldiği bir kod tabanında bu tuhaf duruyor. Bundan hoşlanmamak tutarlı bir tercih, ama çalışan koddan göç etmek için zayıf bir gerekçe: hâlihazırda TypeORM kullanan bir ekibin taşınmak için elindeki neden, 1.0 yayımlanmadan önceki kadar güçlü değil.
Sequelize farklı bir durum. latest etiketi 9 Mart 2026’da yayımlanan 6.37.8’de, v7 ise 4 Şubat 2026’da yayımlanan 7.0.0-alpha.48 ile hâlâ alpha aşamasında. 48 sürüm boyunca alpha’da kalmış bir ana sürüm, tek başına yeterli bir sinyal. Tasarım itirazı da bunun üzerine biniyor: Sequelize’in TypeScript desteği doğuştan değil sonradan eklenmiş; oysa bir TypeScript servisi için veri katmanı seçerken aradığınız özellik tam olarak budur.
Neden doğrudan pg veya postgres.js değil#
Sürücü üzerinde ham SQL meşru bir cevap ve bunun tersini varsayan bir karşılaştırma inandırıcılığını kaybeder. Kazandırdıkları gerçek: soyutlama maliyeti yok, sürüm koşuşturması yok ve yazdığınız sorgu çalışan sorgunun kendisi. Bağımlılık düzeyinde bir seçim zorunluluğu da yok, çünkü pg ve postgres.js yukarıdaki üç aracın da altında duruyor. Asıl karar, zaten göndereceğiniz bir sürücünün üzerine bir katman ekleyip eklemeyeceğiniz.
Vazgeçtikleriniz ise alışılmış argümanın ima ettiğinden dar. Enjeksiyon güvenliği bu yolların hepsinde yerinde duruyor, çünkü o işi parametreli sorgular görüyor. Kayıp üç somut şeye iniyor: sonuç tiplemesi, bir kolon yeniden adlandırıldığında refactor güvenliği ve filtreler koşullu olduğunda birleştirilebilirlik. Çoğu ekibin sonunda bir sorgu kurucusuna varmasının dürüst nedeni bu üçüncüsü. Koşullu bir WHERE cümlesini string parçalarından elle kurmak, ham SQL kod tabanlarının kimsenin dokunmak istemediği bir şeye dönüştüğü yerdir. Bu dönüşüm o kadar yavaş ilerler ki hiçbir commit tek başına hata gibi görünmez.
Sık yapılan hatalar#
- Risk beş join’li bir toplulaştırmadayken değerlendirmeyi
findManyüzerinden yapmak. Üç tablolu bir select’te her araç iyi görünür; asıl çekindiğiniz sorguyu ölçün. - Paket boyutunu dağıtılan artifact yerine yerel
node_modulesüzerinde ölçmek. Bu iki sayı ayrışır ve cold start’ı yalnızca biri etkiler. - Tip katmanının canlı veritabanına karşı denetlendiğini varsaymak; oysa bir insanın senkronize tuttuğu bir dosyaya karşı denetleniyor. Kysely için bu tasarım gereği doğru, diğerleri için de codegen atlandığı her an doğru.
- Prisma 7’ye yükseltirken üretilen client’ın
node_modulesdışına çıktığını ve post-install hook’un kaldırıldığını fark etmemek. Ardından gelen Docker veya CI hatası işe yarar hiçbir yeri işaret etmez. - Bağlantı havuzlamasını bir altyapı kararı değil, veri katmanı özelliği saymak ve seçilen client’ın prepared statement davranışının, önüne konan proxy’yi işlevsiz bıraktığını sonradan öğrenmek.
- 7.0 öncesi bir karşılaştırmanın Prisma’nın Rust engine’i hakkındaki iddialarını tekrarlamak. O mimari 19 Kasım 2025’te varsayılan olmaktan çıktı.
Neyi ölçmeli#
Ölçümleri geçişten önce seçin, çünkü sonrasında her sayı bir gerekçelendirme gibi okunur.
- MB cinsinden dağıtılan artifact boyutu;
node_modulesüzerindeduile değil, Lambda’ya giden zip üzerinden. - Milisaniye cinsinden cold start başlatma süresi; yerel ölçümlerden değil, CloudWatch içindeki
INIT_DURATIONdeğerinden. - Endpoint başına p95 sorgu gecikmesi; ikisi birlikte okunabilsin diye yanına üretilen SQL de kaydedilerek.
- Tepe eşzamanlılıkta aktif veritabanı bağlantı sayısı,
max_connectionsdeğerine karşı. - İlk üç ayda ekibin kaç noktada ham SQL’e indiği. Soyutlamanın iş yüküne uymadığını gösteren en iyi tekil sinyal budur.
- Migration SQL’ini çalışmadan önce bir insanın okuyup okumadığı. Cevabı evet ya da hayır, gösterişsiz bir ölçüt ve bu listedeki her gecikme sayısından daha çok olay habercisi.
Varsayılan yaygın durum için geçerli: Lambda üzerinde çalışan, Postgres tabanlı, baştan sona onu yazan ekibin sahip olduğu yeni bir TypeScript servisi. Varsayılandan iki durumda bilinçli olarak ayrılın. Şema alan modelinin kendisiyse ve ekip veriyi sorgulamaktansa tarif etmeyi tercih ediyorsa Prisma’ya geçin; ama önce havuzlama tasarımının RDS Proxy’ye bağlı olmadığını doğrulayın. Veritabanı başkasına aitse ve tiplerin içeriye değil dışarıya doğru akması gerekiyorsa Kysely’ye geçin. Bu üç durumdan hangisinde olduğunuzu yazılı hâle getirin, çünkü altı ay sonra o cümle benchmark’tan daha değerli olacak.
Kaynaklar#
- Prisma ORM v7.0.0 release notes (yeni sekmede açılır) - 19 Kasım 2025 sürüm tarihi, Rust içermeyen client’ın varsayılan hâline gelmesi ve üretilen client’ın output yolu dahil kırıcı değişiklikler için birincil kaynak
- Prisma 7 Release: Rust-Free, Faster, and More Compatible (yeni sekmede açılır) - Başlık performans ve paket boyutu iddiaları ile
prisma-clientprovider değişikliği - Prisma ORM without Rust: Latest Performance Benchmarks (yeni sekmede açılır) - 14 MB’tan 1,6 MB’a paket boyutu rakamları ve PostgreSQL ile
pgsürücüsü üzerinden benchmark yöntemi - Prisma 7 AMA: Clearing Up the Why Behind the Changes (yeni sekmede açılır) - Üreticinin bazı senaryolarda verim gerilemesini kabul ettiği yazı; pazarlama rakamlarını dengeleyen kaynak
- Caveats when deploying to AWS platforms (yeni sekmede açılır) - RDS Proxy oturum sabitleme ifadesi ve arkasındaki prepared statement mekanizması
- Prisma database connections (yeni sekmede açılır) - Serverless bağlantı yönergeleri, eşzamanlılık sınırı formülü ve PgBouncer ile
DIRECT_URLkalıbı - Plot Twist: We’re All Building the Same ORM (yeni sekmede açılır) - Drizzle ile Prisma’nın yakınsadığını savunan üretici kaynaklı yazı; burada nötr bulgu olarak değil, kaynağı belirtilmiş bir iddia olarak anılıyor
- Drizzle ORM v0 to v1 updates (yeni sekmede açılır) - v1 kırıcı değişikliklerinin, paket düzeninin ve migration klasörü biçiminin yetkili listesi
- Drizzle Relational Queries v1 to v2 (yeni sekmede açılır) -
defineRelations()geçiş yolu; 0.45.2 ile başlayan bir ekibi en çok etkileyecek değişiklik - Drizzle ORM releases (yeni sekmede açılır) - Sürüm temposu ve 1.0’a doğru beta’dan release candidate’a ilerleyiş
- Kysely on GitHub (yeni sekmede açılır) - Desteklenen dialektler, çalışma zamanı desteği ve projeyi kimin sürdürdüğü
- Kysely relations recipe (yeni sekmede açılır) - Projenin kendi ifadesiyle Kysely’nin ORM olmadığı ve ilişki kavramı taşımadığı
- Kysely migrations (yeni sekmede açılır) - Sade migrator, elle yazılan
upvedown, çalıştırma kilidi vekysely-ctlaracının çekirdek dışında kalması - TypeORM releases (yeni sekmede açılır) - 19 Mayıs 2026’da 1.0.0 ve 13 Temmuz 2026’da 1.1.0, kesin tarihleriyle sürüm akışı
- TypeORM Reaches 1.0 after Nearly a Decade (yeni sekmede açılır) - Bakım canlanmasının sayıları ve 1.0 ile neyin değiştiği
- Sequelize releases (yeni sekmede açılır) - Kararlı hat olarak v6.37.8 ve hâlâ alpha olan v7 için 4 Şubat 2026 tarihli v7.0.0-alpha.48
İlgili yazılar
Aurora mimarisi, I/O maliyet analizi ve RDS yerine ne zaman seçilmesi gerektiğine dair rehber; migration stratejileri ve gerçek karar çerçeveleriyle.
aws · data-storage-orm · postgresql +3
Milyonlarca kullanıcıya hizmet veren kurumsal bildirim sistemleri için tasarım desenleri, veritabanı şemaları ve mimari kararlar
typescript · postgresql · architecture +4
DynamoDB'de OFFSET, keyfi ORDER BY ve ucuz COUNT yok. İmzalı next/prev cursor sunun, sıralamayı sort key ile modelleyin, toplam sayıyı listeden çıkarın.
dynamodb · aws · data-storage-orm +2
CDK TypeScript Lambda için 9 bundler ve 3 cdk synth runner'ının ölçümlü karşılaştırması; her katman için varsayılan ve onu seçtiren kural.
aws-cdk · lambda · typescript +3
AppSync subscription'ları yalnızca mutation ile tetiklenir. Downstream BFF olaylarını NONE veri kaynaklı bir mutation'a EventBridge ve CDK ile köprülemeyi inceliyorum.
aws · graphql · serverless +4