generated at
Node.jsのORMについて
概要
Node.jsにはORM沢山存在します
ここではNode.jsに存在するいくつかのORMについて紹介します
ORMではなくクエリビルダーなどに関する内容についてはTypeScriptでタイプセーフにSQLを実行するにまとめています
ORMに関する各種デザインパターンなどについてはORMで使用されるデザインパターンについてnpmパッケージを元に考えるにまとめています

前置き
ここにある内容はあくまで筆者個人の意見や経験などに基づいたものなので、鵜呑みにはせず、あくまで参考程度にとどめていただけると幸いです🙏
実際に採用する際は、事前に検証や調査などをしてから決定することを推奨します

おそらく、ここで紹介している中では一番歴史の長いORM
npm trendsを見る限りは、おそらくNode.jsORMの中では最も使用率が高いと思われます (ただしnpm trendsを見る限り、2024/04ごろから徐々にPrismaが追い抜きつつあるように見えます)
Node.jsORMが乱立しがちな印象ですが、Sequelizeについては10年以上生き残り続けており、今でも開発やメンテナンスが継続されています。個人的には悪くないライブラリだと思っています。
Active Recordパターンを採用しており、RailsLaravelなどのフレームワークの経験がある方は比較的馴染みやすいAPIなのではないかと思います

npm trendsを見る限り、2024/04ごろから徐々にSequelizeのダウンロード数を追い抜きつつあるようで、かなり勢いがありそうです
独自のDSLを使ってスキーマを記述し、その情報を元にクライアント(Prisma Client)やマイグレーションなどを自動生成します
スキーマやクライアント(Prisma Client)によって背後のデータベースを抽象化し、スキーマに基づいてタイプセーフに問い合わせができるなどのメリットがあります。
また、GUIのDBクライアントもついてきます (Prisma Studio)
上記のように、全体的にユーザーに高い生産性を提供するという点が強く意識されている印象です
また、Cloudflare WorkersNeon, libsqlなど、サーバーレスランタイムにおけるサポートも進んでいる印象
Prisma Data Proxyなどのサービスも提供されています
MongoDBもサポートされています
Prisma TypedSQLというsqlcPgTypedライクな機能も提供されます

Active Record/Data Mapperの両方のデザインパターンを採用しており、小規模〜大規模まで幅広く使用できることが意識されています
TypeScriptとの相性を考慮して作成されている
ネックな点
2024現在、まだメジャーリリースされていない
MisskeyVendureなどのOSSで採用実績があるのは大きいとは思うものの、まだ破壊的変更が起こる可能性が考えられます
Decorator metadataなどの実験的機能に依存
これについてはTypeORMEntitySchemaという機能を提供していて、これを使えば一応デコレータやDecorator metadataに依存せずにマッピングを定義することも可能です (ただし、この機能はあまり使用されていない印象はあります)
以下のような特徴があり、比較的幅広いニーズなどを想定して開発されている印象があります
Active Record/Data Mapperパターンの両方に対応している
EntitySchema によりデコレータを使用せずにマッピングを定義可能
また、これによりドメインモデルからマッピング定義を切り離すことができる
ただ、ネックな点にもあげましたが、Sequelizeなどと比較した際にまだメジャーリリースされていないことなどもあり、少しリスキーな部分もあるかもしれないです。
MongoDBもサポートされています
TypeORMの現在の動向などについてはTypeORMの現在の動向と今後について (2024年)にまとめています

Data Mapperパターンを採用したORM (実際に使ったことはないです)
TypeORMとは異なり、Active Recordパターンは未サポート
Unit of WorkパターンをサポートしているのがTypeORMとの大きな違いだと思います。
Unit of Workパターンを実現するためにMikroORMが提供する Collection 型を利用する必要があり、ここについては多分、人によって好みが分かれそうな部分な気がします (Use pure arrays instead of collections when using EntitySchema (#2683))
マッピングの定義方法
TypeORM同様、デコレータ+reflect-metadataを使った方法をサポート
他にも、ts-morphを使う方法も提供されているみたいです
また、TypeORM同様、 EntitySchema を使用することで、マッピング対象のクラスとマッピングの定義を分離することも可能
また、MongoDBサポートも重要視されているようです
libsqlもサポート

v1.5時点ではまだ実験的みたいですが、RedwoodRedwoodRecordというORMを提供しているようです。
Prismaをベースとしており、Active Recordパターンを採用しています。

Knex.jsをベースにしたORM
Sequelize同様、Active Recordパターンを採用しています
insertGraph upsertGraph などの機能が強力な印象

Knex.jsベースのORM
Ghostで採用実績があります
比較的大規模なOSSで採用実績があるのは大きいものの、2021年でコミットが止まっていそうではあります

名前にORMとはついているものの、ORMというよりはどちらかと言うとクエリビルダーに近いと思います
kyselyKnex.jsなどのクエリービルダーと比較すると、おそらくPrismaに影響を受けたと思われる問い合わせAPIを提供している点が違いなのかなと思います (TypeScriptでタイプセーフにSQLを実行する)
Prismaとはおそらく以下のような点などで差別化が狙われているのではないかと推測しています
kyselyKnex.jsライクなクエリの構築機能を提供する
エンジンが不要で、より軽量である点 (Cloudflare Workersなど、フットプリントの小さいライブラリが必要な場合にやや有利かもしれません)
GitHubのスター数などを見る限り、Drizzle ORMもかなり勢いはありそうですが、2024/05時点ではまだメジャーリリースされていません
今後、APIに破壊的変更などが入る可能性などもまだあるかと思います

Node.jsにおけるORMに関する変遷
〜2015年くらいまでは、おそらくRailsなどのコミュニティから影響を受けて登場したと思われるORMが主流であった印象
例)
これは厳密にはORMではないですが、APIとしてはおそらくactiverecordに強く影響を受けていると思われます
Active Recordパターンを実装したORMが多く、この時期はRailsなどの影響が大きかったのではないかと推測します
2015年くらいからは、TypeScriptの採用が少しずつ増え始めたことにより、それらをより活用しやすいORMが少しずつ増えていった印象です
例)
TypeORM - Data Mapperパターンを実装しており、おそらくJVM.NET系などのORMから影響を受けているのではないかと思われます
Objection.js - こちらはSequelizeなどと同様、Active Recordパターンを実装しています。また、TypeScriptの型定義を活かしつつ柔軟にクエリを書けるようにすることなども意識されているように見えます
2020年ごろから、ORMというよりはどちらかというとより軽量なクエリビルダーのようなライブラリが徐々に増えつつあるようです
例)
Kysely (※これは正確にはORMではなくクエリビルダー)
上記ライブラリの共通点として、TypeScriptでの活用を念頭に起きつつ、DTOへのマッピングのみをサポートするシンプルな仕組みが採用されています
既存のSequelizeTypeORMなどのORMドメインモデルへのマッピングを提供することが意図されていたため、より軽量な作りになっています
背景としてはおそらく、以下のあたりがあるのではないかと思います
Node.jsがサーバーサイドで選択される際のユースケースの一つとしてWebサービスのバックエンド以外にも、Next.jsRemixなどを使用したWebサイトでの採用も結構な割合で存在するのではないかと思っていて、そういった場合、重厚なORマッピングの仕組みがなくとも十分にワークする
この場合、タイプセーフにクエリを書ければ十分というケースが多く、こういったライブラリの使用が適している場合が多いのではないかと思います
Cloudflare Workersなどではフットプリントが少なめのライブラリが好まれる (Kysely, Drizzle ORMなど)
2015年ごろからTypeScriptの影響によりNode.jsでもData Mapperパターンを実装したORMが現れはじめましたが、こういったORMJVM.NET系のコミュニティでは比較的好まれやすい印象があるものの、元がスクリプト言語であるTypeScript (JavaScript)では受け入れられにくかった可能性もあるのではないかと思います
JavaScriptはクラスを定義せずともオブジェクトを作成することができ、こういったライブラリはJavaScriptのそういった特性と相性が良いこと
ただし、MikroORMのような古典的なData Mapperパターンを実装したORMも引き続き登場してはいます
こういったORMNode.jsでバックエンドをモノリシックなアーキテクチャに従って開発していくような場合は、依然として需要は残り続けるのではないかと思います

採用基準について
使用率・安定性
使用率や安定性などの観点からすると、SequelizeまたはPrismaのいずれかが無難ではないかと思います (npm trendsによるとこの2つが最も使用率が高い)
Sequelizeは10年以上ずっと開発やメンテナンスが継続されて続けています
Prismaについても安定して一定間隔ごとにリリースが継続されている印象です

アプリケーションのアーキテクチャについて
開発スピードなどを重視したいという場合はSequelizeObjection.js, Prisma, Drizzle ORMなどが使いやすいのではないかと思います
Sequelizeについては、以下のような理由もあり選択肢としては比較的無難な気がしています
Node.jsORMとしては最も枯れている
現在も継続してメンテナンスや開発、改善が行われている
npm trendsを見る限りユーザー数も多い
おそらく多くのユーザーにとって馴染みやすいと思われるActive Recordパターンを採用している
Prismaはどちらかといえばサーバーレスアーキテクチャーなどを想定して開発されているような印象を受けました。こういった分散アーキテクチャーを採用したシステムでは相性が良さそうです。
Prisma Data Proxyによるコネクションプーリングが提供されている
公式でCloudflare D1Neonlibsqlなどのサポートが提供されている
また、将来的にはPrismaが一番人気なORMになる(=>エコシステムやコミュニティが充実している)可能性も結構ありそうな気はしているので、それを見越した上でPrismaを採用しておくのもありなのかもしれません
Drizzle ORMも勢いはありそうではあるものの、2024/05時点ではメジャーリリースされていない点がネックだとは思います
より軽量でCloudflare Workersなどとの相性も良いと思われるため、将来的にはPrismaの競合になる可能性は十分にあるのではないかと思います
いわゆるレイヤードアーキテクチャーやその派生アーキテクチャーなどに従いつつ、ドメインロジックはドメインモデルパターンに従って実装していきたいというケースでは、Data Mapperパターンを採用しているTypeORMMikroORMなどが相性がよいのではないかと思います
対象ドメインが複雑な場合は、こういったスタイルとは相性が良いでしょう。しかし、Next.jsRemixなどを使ってWebサイトを作りたい、というケースではやや過剰になる場合もあるかもしれません。
この場合にPrismaを採用すると、Prismaは基本的にリレーションからシンプルなDTOへのマッピングしか提供されないため、二度手間が発生します (Prismaが返却したDTOに対して、さらに手動でドメインモデルへのマッピングが必要になる)
ただし、そもそもNode.jsはこういったスタイルの開発が向いていないような気も個人的にはしていて、こういったきっちりと設計をして開発を進めていきたいようなケースでは、JVM.NET系の言語などを採用した方がやりやすいような気もしています (JVM.NET系の言語と比較すると、どうしてもORMやフルスタックフレームワークの成熟度がやや追いついていない印象を受けるため)

採用するデータベースについて
MongoDBを採用する場合は、以下のあたりが選択肢になると思います
Mongoose (これは厳密にはORMではありません)
この中だと、Mongoose, Prisma, MikroORMあたりがよさそうに見えます

クエリをタイプセーフに記述したいかどうか?
この用途を満たすことを考えるとPrismaDrizzle ORMあたりが優秀だと思います
ただし、それ以外のORMをすでに採用している場合でも、sqlcpgtyped, kyselyなどのライブラリを併用することで、タイプセーフにクエリを記述することは可能だと思います
なので、もしSequelizeなどのORMを採用している既存のプロダクトがある場合でも、無理にPrismaなどへORMそのものを移行するというよりは、これらのライブラリを併用した方がコストを抑えられる可能性もあるかもしれません
また、CQRSなどの考えに基づいて考えると、ORMの必要性が高いのはどちらといえばコマンドのレイヤーになるのではないかと思います。無理にORMだけで複雑なクエリを構築しようとするよりも、部分的にこういったライブラリを採用し、用途に応じて使い分けた方が結果として実装がシンプルになるケースもあるかもしれません (ORMだけであらゆることを実現しようとする必要はない)
ただし、その場合はORMとそれらのライブラリとの間でコネクションプールを共有するなど、少し工夫は必要になるかもしれません

パフォーマンス
PrismaによってORM Benchmarksが公開されています
2024/07時点の情報です
Prisma/Drizzle ORM/TypeORMが比較されており、大抵のユースケースではTypeORM > Prisma > Drizzle ORMといった結果が出ているようです

関連ページ