Getting Started
Install and configure prisma-ltree in a Prisma Next Postgres app
This guide wires the prisma-ltree extension pack into a Prisma Next Postgres project. It assumes you already have a Prisma Next app scaffold (prisma-next.config.ts, emitted contract, and a db.ts runtime entrypoint).
Installation
pnpm add prisma-ltreeprisma-ltree pins exact @prisma-next/* versions. Align your framework packages with the extension's peer dependency before continuing.
Configuration
Register the pack in prisma-next.config.ts:
import ltree from "prisma-ltree/control";
import { defineConfig } from "@prisma-next/postgres/config";
export default defineConfig({
contract: "./src/prisma/contract.ts",
extensions: [ltree],
db: {
connection: process.env.DATABASE_URL!,
},
});Projects using the verbose multi-import config shape use the same control import with extensionPacks: [ltree] instead of extensions.
Contract
Declare ltree columns in either authoring lane: contract.prisma (PSL) or contract.ts (TypeScript). Both emit the same compiled contract. See Authoring Contracts for the PSL surface (ltree.Ltree() and ltree.LtreeArray()) and a side-by-side comparison.
This guide uses the TypeScript contract with ltree() from prisma-ltree/column-types.
import { int4Column, textColumn } from "@prisma-next/adapter-postgres/column-types";
import sqlFamily from "@prisma-next/family-sql/pack";
import { defineContract, field, model } from "@prisma-next/sql-contract-ts/contract-builder";
import { ltree } from "prisma-ltree/column-types";
import ltreePack from "prisma-ltree/pack";
import postgres from "@prisma-next/target-postgres/pack";
export const contract = defineContract({
family: sqlFamily,
target: postgres,
extensionPacks: { ltree: ltreePack },
models: {
Category: model("Category", {
fields: {
id: field.column(int4Column).id(),
name: field.column(textColumn),
path: field.column(ltree()),
},
}).sql({ table: "category" }),
},
});Re-emit after contract edits:
pnpm prisma-next contract emitRuntime
Register codecs and query operations at execute time:
import ltree from "prisma-ltree/runtime";
import postgres from "@prisma-next/postgres/runtime";
import type { Contract } from "./contract.d";
import contractJson from "./contract.json" with { type: "json" };
export const db = postgres<Contract>({
contractJson,
extensions: [ltree],
url: process.env.DATABASE_URL!,
});Control and contract wiring alone are not enough. Queries fail or lack ltree methods without prisma-ltree/runtime in extensions.
Database setup
The pack ships a baseline migration that runs CREATE EXTENSION IF NOT EXISTS ltree. Apply it with Prisma Next's control plane:
pnpm prisma-next db initFor projects using migration history, use migration plan and migrate instead. On brownfield databases that already have ltree enabled, emit the contract and run db sign / db verify to align the marker.
Inserting tree paths
Paths are plain strings validated by the codec (dot-separated labels, e.g. electronics.computers.laptops). Build and insert them in application code:
import { db } from "./prisma/db";
const category = db.schema.tables.category;
async function seedCategories() {
const runtime = await db.runtime();
await runtime.execute(
db.sql.public.category
.insert([
{ path: "electronics", name: "Electronics" },
{ path: "electronics.computers", name: "Computers" },
{ path: "electronics.computers.laptops", name: "Laptops" },
])
.returning("id", "path", "name")
.build(),
);
}Basic queries
Ltree operators attach to column references in the SQL query builder (or on ltree fields in the optional ORM lane). They do not appear as nested Prisma Client where objects.
import { db } from "./prisma/db";
import { param } from "@prisma-next/sql-query/param";
const category = db.schema.tables.category;
const plan = db.sql
.from(category)
.select({ id: category.columns.id, path: category.columns.path })
.where(category.columns.path.isDescendantOf(param("prefix")))
.build({ params: { prefix: "electronics" } });
const rows = await db.runtime().execute(plan);See Hierarchy Operators and Pattern Matching for the full operator set.