You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Surfaced from a Medusa-vs-Perry compatibility study (#419 was filed from the same study). The takeaway: legacy Node ORMs (MikroORM, TypeORM) are decorator + Reflect.metadata + Proxy-driven and are a multi-person-year shim job that locks Perry to upstream cadence. Drizzle was built specifically for AOT/edge runtimes (Workers, Bun, Deno) — same constraints Perry has — and is the natural Perry-side choice.
Schema is plain TS values — pgTable("users", { id: serial(...), name: text(...) }). No decorators, no Reflect.metadata, no runtime class generation.
Query builder composes at the type level — TS magic, not runtime magic. The compiled output is just method chains over an object.
Migrations are dev-time (drizzle-kit) — the migration generator never has to live inside the produced binary.
No ORM identity-map / unit-of-work — explicit await db.insert(...), no surprise side effects, AOT-friendly.
Already runs on Cloudflare Workers, Bun, Deno — every AOT/edge runtime Drizzle-team had to support gave Perry a head start.
Drivers Drizzle uses are exactly the ones perry-stdlib already ships: pg, mysql2, sqlite. So the wire layer is in place.
Prisma and Kysely are noted alternatives. Kysely is a smaller-scope follow-up worth considering (query builder only, no schema/migrations — even more AOT-natural). Prisma does not fit Perry's single-binary model (separate Rust query engine binary) and is out of scope here.
Scope
End-to-end means: user does npm install drizzle-orm postgres (or pg), adds "compilePackages": ["drizzle-orm"] to package.json, writes a standard Drizzle program (schema + queries), runs perry compile app.ts -o app && ./app, and gets a single-file native binary that talks to a real Postgres.
Likely shake-out areas:
drizzle-orm source compilation — Drizzle is mostly TS, no native bindings. Most should compile out of the box because the lib was already engineered to avoid eval, Function(), runtime metadata. Expect individual TS-subset features each module trips over (the standard compilePackages shake-out, same shape as Compile ink (React-based TUI framework) end-to-end via perry.compilePackages #348).
Driver glue — Drizzle's pg-core / mysql-core / sqlite-core hand off to the underlying client. Need to verify the existing pg, mysql2, better-sqlite3-shaped clients in perry-stdlib line up with what Drizzle calls.
Type-level query DSL — purely a TS-compile-time concern; Perry uses SWC for parsing and shouldn't have a problem with the heavy generic gymnastics, but worth a real test.
drizzle-kit (migrations) — separate concern, not strictly required to be Perry-compiled (it's a dev tool the user runs from Node). Could be a follow-up if there's interest.
Acceptance
Schema definition + insert/select/update/delete + a relation join in a 50-line program compiles via perry compile, produces a single-file native binary, runs against a real Postgres, and matches the same program under node --experimental-strip-types.
One of: pg, mysql2, sqlite drivers verified end-to-end. Others as follow-up.
Whatever shake-out fixes are needed in perry-codegen / perry-stdlib to make the dependency tree compile cleanly, land them under this umbrella.
Out of scope (separate follow-ups)
drizzle-kit (migration generator) compiling natively — it's a dev-time tool; users can run it from Node.
Kysely as a compilePackages target — separate, smaller-scope tracking issue.
Shimming MikroORM / TypeORM / Prisma — explicitly not the path; those are the legacy-Node lineage that Perry's stdlib selections (fastify, pg, ws over their heavier siblings) have already opted out of.
A Perry-native ORM written from scratch — bigger lift than wiring Drizzle and competes with a thriving library; skip unless Drizzle turns out to be unworkable.
Strategic context
Companion to a Hono compilePackages tracking issue (filed alongside this one). Together they cover the modern AOT-friendly TS backend stack — the same selection that Workers/Bun/Deno users have converged on for the same reasons Perry has.
Tracking issue for landing
drizzle-orm(https://github.com/drizzle-team/drizzle-orm) as aperry.compilePackagestarget.Surfaced from a Medusa-vs-Perry compatibility study (#419 was filed from the same study). The takeaway: legacy Node ORMs (MikroORM, TypeORM) are decorator +
Reflect.metadata+ Proxy-driven and are a multi-person-year shim job that locks Perry to upstream cadence. Drizzle was built specifically for AOT/edge runtimes (Workers, Bun, Deno) — same constraints Perry has — and is the natural Perry-side choice.Why Drizzle (vs. shimming MikroORM/TypeORM/Prisma)
pgTable("users", { id: serial(...), name: text(...) }). No decorators, noReflect.metadata, no runtime class generation.drizzle-kit) — the migration generator never has to live inside the produced binary.await db.insert(...), no surprise side effects, AOT-friendly.perry-stdlibalready ships:pg,mysql2,sqlite. So the wire layer is in place.Prisma and Kysely are noted alternatives. Kysely is a smaller-scope follow-up worth considering (query builder only, no schema/migrations — even more AOT-natural). Prisma does not fit Perry's single-binary model (separate Rust query engine binary) and is out of scope here.
Scope
End-to-end means: user does
npm install drizzle-orm postgres(orpg), adds"compilePackages": ["drizzle-orm"]topackage.json, writes a standard Drizzle program (schema + queries), runsperry compile app.ts -o app && ./app, and gets a single-file native binary that talks to a real Postgres.Likely shake-out areas:
drizzle-ormsource compilation — Drizzle is mostly TS, no native bindings. Most should compile out of the box because the lib was already engineered to avoideval,Function(), runtime metadata. Expect individual TS-subset features each module trips over (the standardcompilePackagesshake-out, same shape as Compileink(React-based TUI framework) end-to-end viaperry.compilePackages#348).pg-core/mysql-core/sqlite-corehand off to the underlying client. Need to verify the existingpg,mysql2,better-sqlite3-shaped clients inperry-stdlibline up with what Drizzle calls.drizzle-kit(migrations) — separate concern, not strictly required to be Perry-compiled (it's a dev tool the user runs from Node). Could be a follow-up if there's interest.Acceptance
perry compile, produces a single-file native binary, runs against a real Postgres, and matches the same program undernode --experimental-strip-types.perry-codegen/perry-stdlibto make the dependency tree compile cleanly, land them under this umbrella.Out of scope (separate follow-ups)
drizzle-kit(migration generator) compiling natively — it's a dev-time tool; users can run it from Node.compilePackagestarget — separate, smaller-scope tracking issue.Strategic context
Companion to a Hono
compilePackagestracking issue (filed alongside this one). Together they cover the modern AOT-friendly TS backend stack — the same selection that Workers/Bun/Deno users have converged on for the same reasons Perry has.