ORM adapters
v0.6.0 added catch-all resolvers for Prisma, Drizzle, and Kysely. v0.7.0 adds schema inference — you can skip hand-writing MeshSchema and import it from your ORM.
MeshQL still owns parsing, planning, list filters, and access plugins. The adapter maps JoinPlan → ORM calls.
When to use which adapter
Section titled “When to use which adapter”| Adapter | Best for | Returns | Shaper |
|---|---|---|---|
@meshql/prisma |
Existing Prisma apps | Nested JSON from Prisma select |
Skipped (preshaped: true) |
@meshql/drizzle |
Drizzle relational query API | Nested JSON from with |
Skipped (preshaped: true) |
@meshql/kysely |
Kysely + raw SQL control | Flat aliased rows | Runs (like buildSelectSql) |
@meshql/postgres / @meshql/sqlite |
Full SQL control | Flat aliased rows | Runs |
Prisma and Drizzle return already-nested objects, so register with { preshaped: true }. Kysely uses the same SQL builders as the Postgres/SQLite packages.
Shared requirements
Section titled “Shared requirements”- MeshQL schema — hand-written, or inferred via
schemaFromPrisma/schemaFromDrizzle. Entity names should match Prisma model keys or Drizzledb.querykeys. - Catch-all resolver —
mesh.resolve("*", …). Entity-specific resolvers always override"*". - Shared DB client — create once at startup; see Database connections.
Schema inference (v0.7.0)
Section titled “Schema inference (v0.7.0)”import { createMesh, extendSchema } from "@meshql/core";import { schemaFromPrisma, withPrisma } from "@meshql/prisma";
const schema = extendSchema(await schemaFromPrisma("./prisma/schema.prisma"), { entities: { user: { fields: ["id", "name"] } }, // hide email / role});
const mesh = createMesh(schema);withPrisma(mesh, prisma, { schema });Drizzle:
import { schemaFromDrizzle, withDrizzle } from "@meshql/drizzle";import * as tables from "./db/schema.js";
const schema = schemaFromDrizzle(tables);withDrizzle(mesh, db, { schema });extendSchema from @meshql/core merges overrides: entity fields arrays are replaced (so you can hide), and joins can be added or removed.
Prisma
Section titled “Prisma”Install
Section titled “Install”npm install meshql-prisma meshql-core @prisma/client# ornpx jsr add @meshql/prisma @meshql/coreimport { PrismaClient } from "@prisma/client";import { createMesh } from "@meshql/core";import { schemaFromPrisma, withPrisma } from "@meshql/prisma";
const prisma = new PrismaClient();const schema = await schemaFromPrisma("./prisma/schema.prisma");const mesh = createMesh(schema);
withPrisma(mesh, prisma, { schema });withPrisma is equivalent to:
import { prismaResolver } from "@meshql/prisma";
mesh.resolve("*", prismaResolver(prisma, { schema }), { preshaped: true });Schema mapping
Section titled “Schema mapping”- MeshQL entity
user→prisma.userdelegate - Join
post.comments→ nestedselect: { comments: { select: { … } } } table/columnson entities map MeshQL field names to DB columns for filters and ordering
Example
Section titled “Example”Runnable demo: examples/express-prisma.
pnpm --filter express-prisma db:pushpnpm --filter express-prisma startPackage reference: packages/prisma/README.md.
Drizzle
Section titled “Drizzle”Install
Section titled “Install”npm install meshql-drizzle meshql-core drizzle-orm# ornpx jsr add @meshql/drizzle @meshql/coreimport { schemaFromDrizzle, withDrizzle } from "@meshql/drizzle";import * as tables from "./db/schema.js";
const schema = schemaFromDrizzle(tables);withDrizzle(mesh, db, { schema });Requires Drizzle’s relational query API: db.query.posts.findMany({ with: { … } }). Entity post with table: "posts" maps to db.query.posts.
Package reference: packages/drizzle/README.md.
Kysely
Section titled “Kysely”Install
Section titled “Install”npm install meshql-kysely meshql-core meshql-postgres kysely# SQLite: meshql-sqlite instead of meshql-postgres# ornpx jsr add @meshql/kysely @meshql/core @meshql/postgresimport { withKysely } from "@meshql/kysely";
withKysely(mesh, db, { schema, dialect: "postgres" });Kysely executes parameterized SQL from @meshql/postgres or @meshql/sqlite. Returns flat rows; the MeshQL shaper nests the response.
import { kyselyResolver } from "@meshql/kysely";
mesh.resolve("*", kyselyResolver(db, { schema, dialect: "sqlite" }));// no { preshaped: true }Package reference: packages/kysely/README.md.
List queries and point reads
Section titled “List queries and point reads”All three adapters support:
- Point read —
GET /mesh/post/1→findUnique/findFirstwithwherefromplan.context.entityId - List —
plan.listwith limit, cursor,orderBy, and filters (mapped to ORM/SQL equivalents)
Use @meshql/client with the list option; it serializes $list into the signed query payload.
Nested fields
Section titled “Nested fields”Multi-level nesting (e.g. post.comments.author.name) is supported end-to-end since v0.5.1. ORM adapters build nested select / with trees from the join plan.
What’s not included yet
Section titled “What’s not included yet”- Automatic transaction wrapping
- Write/mutation resolvers (reads only in adapters)
schemaFromKysely(Kysely still uses a hand-written MeshSchema + SQL builders)
Related
Section titled “Related”- Database connections
- SQL integration
- Concepts — JoinPlan and shaper