@farming-labs/orm

Redis and Upstash Redis

Redis support in Farming Labs ORM is the key-value runtime family for teams that want one storage layer across:

The goal is not to turn Redis into a relational database. The goal is to keep one schema and one ORM surface when the storage contract is key-value friendly.

What this gives you

You still write the schema and storage layer once.

Then the runtime translates that layer into Redis-backed operations with:

This is a strong fit for sessions, verification tokens, cache metadata, rate limit buckets, lightweight billing or auth state, and other package-owned state that does not need heavy relational planning.

Create the runtime directly

redis-runtime.ts
import { createClient } from "redis";
import { createOrm } from "@farming-labs/orm";
import { createRedisDriver } from "@farming-labs/orm-redis";
import { appSchema } from "./schema";

const redis = createClient({
  url: process.env.REDIS_URL,
});

await redis.connect();

const orm = createOrm({
  schema: appSchema,
  driver: createRedisDriver({
    client: redis,
  }),
});

Use the runtime helper path

If a framework or package wants to accept the raw Redis client and normalize it later, use the runtime helper:

import { createOrmFromRuntime } from "@farming-labs/orm-runtime";

const orm = await createOrmFromRuntime({
  schema: appSchema,
  client: redis,
});

That keeps the package boundary generic instead of forcing a Redis-specific adapter branch.

Upstash Redis fits the same runtime family:

upstash-runtime.ts
import { Redis } from "@upstash/redis";
import { createOrmFromRuntime } from "@farming-labs/orm-runtime";

const redis = new Redis({
  url: process.env.UPSTASH_REDIS_REST_URL!,
  token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});

const orm = await createOrmFromRuntime({
  schema: appSchema,
  client: redis,
});

Setup helpers

Redis is a runtime-first backend, not a schema-push backend.

That means:

import { bootstrapDatabase } from "@farming-labs/orm-runtime/setup";

const orm = await bootstrapDatabase({
  schema: appSchema,
  client: redis,
});

Relations, lookups, and transactions

Redis is not a join-first runtime, so the ORM stays explicit and conservative.

That means:

So the runtime is a good fit for lightweight relational patterns inside a key-value workload, but it should not be presented as a native join runtime.

What is supported well

Important limits

Why it matters

This keeps Redis in the same bigger ORM story: