Support Matrix
This page is the quick answer to:
- which stacks are supported
- whether they are generation-first or runtime-first
- whether the setup path is full, limited, or intentionally a no-op
If you want the full story for one stack, use Integrations. This page is just the short support view.
How to read this
Generationmeans Farming Labs ORM can render app-facing artifacts for that stackRuntimemeans the unified ORM can execute against a real client for that stackSetupmeans the runtime setup helpers are available for that stack
Setup can mean different things depending on the backend:
- relational stacks usually apply real schema or table changes
- document or key-value stacks may use a lighter bootstrap path
- some stacks intentionally keep setup as a no-op when there is no real DDL surface
Basic matrix
| Stack | Generation | Runtime | Setup | Notes |
|---|---|---|---|---|
| Prisma | Yes | Yes | Full | Generated schema.prisma plus live PrismaClient runtime |
| Drizzle | Yes | Yes | Full | Generated schema files plus live Drizzle runtime |
| Kysely | No | Yes | Full | Runtime-first relational integration |
| MikroORM | No | Yes | Full | Runtime-first relational integration |
| TypeORM | No | Yes | Full | Runtime-first relational integration |
| Sequelize | No | Yes | Full | Runtime-first relational integration |
| EdgeDB / Gel | No | Yes | No-op | Runtime bridge through the official Gel SQL client |
| Neo4j | No | Yes | Full | Graph runtime through the official Neo4j driver/session shapes |
| Cloudflare D1 | No | Yes | Limited | Worker-native SQLite binding with local/CI setup helpers |
| Cloudflare KV | No | Yes | No-op | Worker-native key-value runtime |
| Redis / Upstash | No | Yes | No-op | Key-value runtime for Redis and Upstash-compatible clients |
| Direct SQL | Yes | Yes | Full | Safe SQL generation plus direct SQL runtime |
| Supabase | Via SQL | Yes | Mixed | Works through raw PostgreSQL clients or the Supabase JS runtime |
| MongoDB | No | Yes | Full | Native Mongo runtime |
| Mongoose | No | Yes | Full | Mongoose-backed runtime |
| Firestore | No | Yes | Limited | Real runtime, but no SQL-style schema push |
| DynamoDB | No | Yes | Full | Creates one table per model through the runtime setup path |
| Unstorage | No | Yes | No-op | Lightweight key-value/document runtime |
Important details
Relational stacks
Prisma, Drizzle, Kysely, MikroORM, TypeORM, Sequelize, and direct SQL are the strongest fit when the data model is relational or join-heavy.
They also carry the best support for:
- generated numeric IDs
- richer native relation loading
- Postgres-style schema namespaces
- SQL-style setup and schema application
Cloudflare D1
Cloudflare D1 is supported as its own runtime family rather than being folded into a generic SQL alias.
That means:
- pass the real Worker binding or a local Miniflare D1 binding directly
- keep one schema definition and one query surface
- use the same runtime helper path as the other stacks
Two boundaries matter:
- the runtime itself is Worker-friendly
- the setup helpers fit best in local, CI, or other Node-managed bootstrap flows
orm.transaction(...) is available, but the runtime does not claim full
interactive rollback semantics the way a long-lived Node SQL connection can.
EdgeDB / Gel
EdgeDB support is a runtime bridge through the official Gel SQL client.
That means:
- pass the raw Gel client directly
- keep one schema definition and one query surface
- let the app keep its own Gel schema and migration flow
Setup is intentionally conservative here:
pushSchema(...)andapplySchema(...)are no-opsbootstrapDatabase(...)still gives the single convenience entrypoint- the runtime is for query execution, not Gel SDL management
Neo4j
Neo4j is supported as a runtime-first graph backend through the official Neo4j driver and session shapes.
That means:
- pass the raw Neo4j driver or session directly
- keep one schema definition and one query surface
- let the runtime setup helpers create the ORM-owned labels, constraints, and indexes
Two boundaries matter:
- this is not a Cypher-native graph query builder
- relation loading stays conservative and uses follow-up reads instead of claiming native graph traversal planning
Cloudflare KV
Cloudflare KV is supported as its own runtime family rather than being folded into Redis or a generic document-store alias.
That means:
- pass the real Worker
KVNamespaceor a local Miniflare namespace directly - keep one schema definition and one query surface
- rely on fallback relation reads and ORM-managed unique lookups
Setup is intentionally light here:
pushSchema(...)andapplySchema(...)are no-opsbootstrapDatabase(...)still gives the one-shot runtime entrypoint
Redis / Upstash Redis
Redis and Upstash Redis fit as a shared key-value runtime family.
That means:
- pass a Redis client or Upstash Redis client directly
- keep one schema definition and one query surface
- rely on fallback relation reads instead of a native join planner
Setup is intentionally light here:
pushSchema(...)andapplySchema(...)are no-opsbootstrapDatabase(...)still gives a convenient one-shot entrypoint
This runtime is a strong fit for sessions, verification tokens, cache metadata, rate limits, and other lightweight package-owned state. It is not the recommended fit for highly relational or join-heavy workloads.
Supabase
Supabase now works through two honest paths:
- a raw PostgreSQL client connected to Supabase
- the direct Supabase JS runtime
The PostgreSQL path keeps full SQL-style setup helpers. The direct Supabase JS runtime is query-first and keeps setup as a no-op.
Document and key-value runtimes
MongoDB, Mongoose, Firestore, DynamoDB, Cloudflare KV, Redis / Upstash Redis, and Unstorage still work through the same unified ORM API, but they are not SQL runtimes.
That means they rely more on:
- follow-up relation reads instead of joins
- ORM-managed lookup behavior
- backend-specific setup limits
Setup differences
- Cloudflare KV keeps
pushSchema(...)andapplySchema(...)as no-ops - Firestore has a real runtime, but not a SQL-style schema push surface
- DynamoDB setup creates one table per model
- Unstorage intentionally keeps
pushSchema(...)andapplySchema(...)as no-ops because the storage contract is key-value oriented rather than DDL-oriented
Numeric IDs and namespaces
- generated numeric IDs are first-class on the relational runtimes, including D1
- Neo4j, MongoDB, Mongoose, Firestore, DynamoDB, Cloudflare KV, Redis, and Unstorage keep numeric IDs manual-only
- schema namespaces are only meaningful on Postgres-style relational runtimes
Unstorage boundary
Unstorage is useful for:
- sessions
- tokens
- lightweight records
- package-owned state
It is not the recommended runtime for highly relational or join-heavy database workloads.
Where to go next
How is this guide?