Overview & Quick Start
Canonical Payload and Zod fields
@nexload-sdk/payload-schema
v2.0.0 Stable ReleasedCanonical Payload field definitions with reusable Zod schemas.
@nexload-sdk/payload-schema eliminates double-declaration of data validation rules in Payload CMS applications. Define intrinsic validation and normalization once, compile it into ordinary Payload collection fields, and expose the identical Zod schemas to client forms, server actions, and API boundaries.
10-Second Code Snippet
Section titled “10-Second Code Snippet”import { defineEntity, field } from "@nexload-sdk/payload-schema";import { z } from "zod";
// 1. Define intrinsic fields onceexport const productEntity = defineEntity({ name: "Product", fields: { title: field.text({ required: true, trim: true, minLength: 3 }), slug: field.slug({ required: true }), price: field.money({ currency: "USD", required: true }), stock: field.number({ integer: true, safe: true, defaultValue: 0 }), },});
// 2. Export directly to Payload Collectionexport const Products = { slug: "products", fields: productEntity.payload.all(),};
// 3. Derive Zod schemas for forms, Next.js server actions, or RPCexport const createProductSchema = productEntity.schema(({ pick }) => pick(["title", "slug", "price", "stock"], { optional: ["stock"] }));export type CreateProductInput = z.infer<typeof createProductSchema>;What You Get
Section titled “What You Get”- Single Source of Truth: Eliminate discrepancies between frontend Zod validation schemas and backend Payload collection rules.
- 14 Built-In Field Factories: Native factories for
text,textarea,slug,number,money,boolean,date,select,relationship,upload,group,array,richText, andnative. - Automatic Payload Normalization: Injected
beforeValidatehooks guarantee that string trimming, case conversions, and slug formats execute even on writes through the Payload Admin UI and Local API. - Flexible Schema Derivation: Extract custom DTOs (
pick,omit), add custom transformations (.transform()), and perform cross-field validations (.refine()). - Zero Framework Leakage: Outputted schemas are ordinary Zod objects and outputted fields are standard Payload field definitions.
- Compile-Time Immutability: All entity facades and compiled field definitions are frozen to guarantee deterministic runtime behavior.
Installation & Requirements
Section titled “Installation & Requirements”pnpm add @nexload-sdk/payload-schema payload zodWith alternative package managers:
# npmnpm install @nexload-sdk/payload-schema payload zod
# bunbun add @nexload-sdk/payload-schema payload zodCompatibility Requirements
Section titled “Compatibility Requirements”| Package / Runtime | Supported Range | Notes |
|---|---|---|
| Node.js | >=20.9.0 | Server/config safe |
| Payload CMS | >=3.85.0 <4.0.0 | Collection fields engine |
| Zod | >=4.0.0 <5.0.0 | Schema derivation engine |
| Module Format | ESM only | Server and configuration safe |
Core Concepts & Invariants
Section titled “Core Concepts & Invariants”1. One Intrinsic Contract
Section titled “1. One Intrinsic Contract”A field definition owns only the rules intrinsic to that field’s value (e.g. “a product title must be 3-120 characters and trimmed”). Application-specific workflow rules (e.g. “is this field optional during draft creation?”) belong in derived schemas, not in the core entity definition.
2. Dual Boundary Compilation
Section titled “2. Dual Boundary Compilation”When you run defineEntity():
entity.payload.all()compiles standard Payload fields with canonical normalization appended tobeforeValidate.entity.schema()produces pure Zod schemas reflecting the exact same constraints.
3. Synchronous Canonical Schemas
Section titled “3. Synchronous Canonical Schemas”Canonical schemas must execute synchronously. Asynchronous refinements are rejected at definition time with ASYNC_CANONICAL_SCHEMA_UNSUPPORTED to ensure compatibility with Payload’s synchronous field validation lifecycle.
4. Non-Goals
Section titled “4. Non-Goals”The package does not create collections, own access control, replace Payload-generated types, or manage database migrations. Payload remains authoritative for persistence types and database schema.
Quick Start: Building a Complete Entity
Section titled “Quick Start: Building a Complete Entity”import { defineEntity, field } from "@nexload-sdk/payload-schema";
export const articleEntity = defineEntity({ name: "Article", fields: { title: field.text({ required: true, trim: true, minLength: 5 }), slug: field.slug({ required: true }), content: field.textarea({ required: true, maxLength: 10_000 }), status: field.select({ values: ["draft", "published", "archived"] as const, defaultValue: "draft", }), author: field.relationship({ relationTo: "users", required: true, }), },});
// Use in Payload Collectionexport const ArticlesCollection = { slug: "articles", fields: articleEntity.payload.all(),};
// Derive input validation schemaexport const createArticleSchema = articleEntity.schema(({ pick }) => pick(["title", "slug", "content", "author"], { strict: true }));Next Steps
Section titled “Next Steps”- Explore Production Recipes & Modeling Guides for the full 14-field catalog, polymorphic relationships, static vs dynamic defaults, and error diagnostics.
- View the complete API Reference & Field Catalog for all factory options and signatures.