空雲 Blog

Eye catch
Prisma@7 は No Rust でも Rust Free でもない

publication: 2025/11/22
update:2025/11/25

Prisma のジェネレーション時のオプションについて🔗


このあとの話のために、最初にジェネレーション時のオプションについて説明します。


  • provider = "prisma-client"
    TypeScript で PrismaClient のコードを生成し、自分のコードの一部としてビルドに組み込む場合

  • provider = "prisma-client-js"
    JavaScript で PrismaClient のコードを生成し、node_modules 経由で別パッケージとして利用する従来の機能


今回、Prisma@7 で売り出しているのはprovider = "prisma-client"です。


Prisma@7 で生成されたファイルを確認してみる🔗


Rust Free と呼ばれる状態を作るため、以下の設定で PrismaClient の TypeScript 用コードを生成してみます。今回、対象の DB は PostgreSQL とします


  • schema.prisma


1generator client {
2 provider = "prisma-client"
3 engineType = "client"
4 output = "../app/generated/prisma"
5}


ここで生成されたファイル中から、QueryCompiler がどのように呼ばれるのか該当コードを確認します


  • prisma/internal/class.ts から、該当部分を抽出


1async function decodeBase64AsWasm(
2 wasmBase64: string
3): Promise<WebAssembly.Module> {
4 const { Buffer } = await import("node:buffer");
5 const wasmArray = Buffer.from(wasmBase64, "base64");
6 return new WebAssembly.Module(wasmArray);
7}
8
9config.compilerWasm = {
10 getRuntime: async () =>
11 await import("@prisma/client/runtime/query_compiler_bg.postgresql.mjs"),
12
13 getQueryCompilerWasmModule: async () => {
14 const { wasm } = await import(
15 "@prisma/client/runtime/query_compiler_bg.postgresql.wasm-base64.mjs"
16 );
17 return await decodeBase64AsWasm(wasm);
18 },
19};


この部分が何なのかというと、base64 化された QueryCompiler の WASM を取り出して、バイナリにデコードした後、WebAssembly として投入しています。このquery_compiler_bg.postgresql.wasm-base64.mjsは 2,410KB あり、zip 圧縮をかけても 940KB ほどのサイズになります。Prisma を動作させるためには、この WASM が必須です。


QueryCompiler がどのように作られているかというと、以下が該当するコードです。


https://github.com/prisma/prisma-engines/tree/main/query-compiler


はい、Rust です。


Prisma の言っている Rust Free とは何か?🔗


2025/4/30 の記事を見ると、辛うじて書いてあります


https://www.prisma.io/blog/try-the-new-rust-free-version-of-prisma-orm-early-access


Prisma ORM's core engine has undergone a major shift from the Rust based query engine to a leaner TypeScript/WASM core (the Query Compiler).


Rust ベースのクエリエンジン(おそらくネイティブバイナリのこと)から、Query Compiler(TypeScript と WASM を組み合わせたもの)になったということらしいですが、その WASM は Rust 製です。


バンドルサイズが 90%小さくなったというのは、ネイティブバイナリを使用した場合の 14MB が、WASM 化で 1.6MB になったということです。QueryEngine から QueryCompiler の移行によって、WASM が不要になったわけではありません。


そして現在 Prisma は、Rust Free、No Rust という言葉を使い続け、混沌を呼び込んでいます。実際のところは、No native libraries です。


Prisma@7 は No Rust でも Rust Free でもない🔗


Prisma@7 に対する公式 Blog は以下の内容になります。


https://www.prisma.io/blog/announcing-prisma-orm-7-0-0


もうバンドルサイズが何から 90% 減少したのかすら書いてません。さらにprovider = "prisma-client-js"provider = "prisma-client"にすれば rust-free になりそうな記述になってますが、後者は TypeScript のコードが生成されるというだけで、基本的な動作は変わりません。生成された TypeScript のコードは WASM を base64 の状態から読み込むのでバンドルサイズが増えます。現状、メリットがありません。


なぜ WASM を base64 にしているのか🔗


モジュールバンドラ対策です。WASM ファイルを直接読み込むコードがあると、あらゆる環境に対応させる必要があります。WASM ファイルがどう扱われるかは、モジュールバンドラの設定次第であり、あらゆる環境に対する対応地獄が待っています。これを解決する簡単な方法は、JavaScript 内に WASM のバイナリを内包しておき、実行時に WebAssembly として放り込むことです。


Cloudflare のように WASM のモジュールファイルを直接読み込む必要のある環境では runtime の指定で、base64 から読み込むのを回避する必要があります。ちなみにruntime = "workerd"のような指定をした場合、以下のようなコードが生成されます。


1config.compilerWasm = {
2 getRuntime: async () => await import("./query_compiler_bg.js"),
3
4 getQueryCompilerWasmModule: async () => {
5 const { default: module } = await import("./query_compiler_bg.wasm?module");
6 return module;
7 },
8};


?moduleの部分は特定のモジュールバンドラに対する指示です。Cloudflare にはそのような指定方法は存在しません。つまりどういうことかというと、エラーを出して動きません。provider = "prisma-client"を指定して出力したコードは、直接自分で該当部分を削除しない限り動かないのです。


まとめ🔗


Prisma もひどいが、巷の記事もひどい🔗


誤解を招く公式 Blog の責任は大きいのですが、Rust Free、No Rust という部分を WASM を使わなくなったと誤解する記事が乱発されいます。


ちなみに Prisma を No Rust で使う方法として、Prisma Accelerate という Prisma 専用の有料サービスを使う方法があります。Prisma エンジン(Rust 部分)をリモート経由で外部実行する方式です。その機能を内包している Prisma Postgres というサービスがあります。このサービスは Prisma が No Rust をうたい始める前からあったのですが、そちらを利用して Prisma が No Rust になったんだという勘違い記事まで存在しています。そしてそれを参照して、さらに間違った記事が再生産されています。


あらゆる情報を疑う必要がある🔗


私を含め、技術記事は間違いだらけです。有名な人の記事もけっこう間違ってます。そして公式の情報も正しいとは限りません。間違った記事を参照して、さらに間違った記事を再生産しているものも見受けられます。最低限自分で検証するまで、それが正しいということを前提としないでください。