Browse documentation

Adapters

How flowpanel reads and writes your data — Drizzle, Prisma, or your own.

An adapter is the plug between flowpanel's typed admin surface and your data layer. It exposes a small interface (list, get, create, update, delete, introspect, inferSchema) that the framework calls; what's behind that interface is up to you.

First-party adapters

PackageConnects to
@flowpanel/kit/drizzleDrizzle ORM + its schema. Reads $inferSelect for row types.
@flowpanel/kit/prismaPrisma Client + DMMF. Looks up prisma[<modelLower>] at runtime.

Pick one with the adapter toggle in the sidebar to see the matching example. The choice persists per browser via a cookie.

Adapter exampleToggle in the sidebar
import { defineAdmin, resource } from "@flowpanel/kit";
import { drizzleAdapter } from "@flowpanel/kit/drizzle";
import { db } from "@/server/lib/db";
import * as schema from "@/server/lib/db/schema";

export default defineAdmin({
  adapter: drizzleAdapter({ db, schema }),
  auth: { /* ... */ },
  resources: [
    resource(schema.users, { columns: ["email", "role"] }),
  ],
});
import { defineAdmin, resource } from "@flowpanel/kit";
import { prismaAdapter } from "@flowpanel/kit/prisma";
import { prisma } from "@/lib/prisma";

export default defineAdmin({
  adapter: prismaAdapter({ prisma }),
  auth: { /* ... */ },
  resources: [
    resource("User", { columns: ["email", "role"] }),
  ],
});

prismaAdapter keys the delegate off the model name's lower-cased form (prisma.user, prisma.order), so pass the PascalCase model name from schema.prisma.

Custom adapters

If you don't use Drizzle or Prisma, implement the Adapter interface directly. It's documented in packages/core/src/types/adapter.ts — six async methods (list, get, create, update, delete, restore), two sync introspection helpers (introspect, inferSchema), and a kind discriminant.

Why two adapters

The two first-party adapters exist because flowpanel doesn't ship its own ORM. You bring the schema and the client; flowpanel reads them.