v3.3.1
Playground
API Reference

Specialized Helpers

Specialized Zod helpers for Mongoose-specific types.

Specialized Helpers

Mongoose provides several specialized types, such as ObjectId and Buffer. @nullix/zod-mongoose includes dedicated helpers to easily define these types in your Zod schemas.

zObjectId(options?)

Helper to create a Zod schema representing a Mongoose ObjectId.

  • options: Optional MongooseMeta for this field.

By default, zObjectId() creates a required Zod field (unless .optional() is used) but omits the field from the generated Mongoose schema. This allows Mongoose to manage the automatic generation and internal lifecycle of the _id field without conflicts.

Use a separate create schema without _id for request bodies. See Model and Input Types.

import { z } from 'zod/v4';
import { zObjectId } from '@nullix/zod-mongoose';

const UserZodSchema = z.object({
  _id: zObjectId(), // Required for Zod validation, omitted from Mongoose schema
  name: z.string(),
});

To explicitly define the _id field in the Mongoose schema (e.g., to add an index, a custom getter, or to disable auto-generation), use the includeId: true flag.

const CustomIdSchema = z.object({
  _id: zObjectId({ includeId: true, index: true }),
});

Population

Mongoose allows you to reference documents in other collections using ObjectIds. @nullix/zod-mongoose provides a comprehensive way to handle these references, ensuring type-safety and validation for both unpopulated (ID) and populated (object) states.

zRef(ref, schema, options?)

Helper for fields that can be either an ObjectId (unpopulated) or a populated object.

  • ref: The name of the Mongoose model being referenced.
  • schema: The Zod schema representing the populated object.
  • options: Optional MongooseMeta for this field.

During Zod validation, zRef accepts either an ObjectId or a full object that matches the provided schema. If an object is provided, it must contain an _id field, which will be extracted. The output of the Zod validation is always an ObjectId (or its string representation in frontend mode, which is automatically enabled in browser environments).

reference-validation.ts
import mongoose from 'mongoose';
import {z} from 'zod/v4';
import {zObjectId, zRef} from '@nullix/zod-mongoose';

const UserSchema = z.object({_id: zObjectId(), name: z.string()});
const PostSchema = z.object({
  author: zRef('User', UserSchema),
});

const userId = new mongoose.Types.ObjectId();
PostSchema.parse({author: userId});
PostSchema.parse({author: {_id: userId, name: 'Ada'}});
// Both return an ObjectId in author.

PopulatedSchema<T, K>

TypeScript utility type to extract the populated object type from a Zod schema. For fluent type tracking through chained .populate() calls, see Strict Model.

  • T: The Zod schema (e.g., typeof PostSchema) or an inferred type.
  • K: The key(s) to populate. If omitted, all zRef fields will be populated recursively.
populated-type.ts
import type {PopulatedSchema} from '@nullix/zod-mongoose';

type PopulatedPost = PopulatedSchema<typeof PostSchema, 'author'>;

populateZodSchema(schema, keys?)

Runtime helper to create a new Zod schema where specific zRef fields are replaced by their underlying refSchema. This is useful when you want to validate already-populated data (e.g., in a frontend application or an API endpoint that receives populated objects).

  • schema: The Zod schema to populate.
  • keys: Optional array of keys to populate. If omitted, all zRef fields will be populated recursively.
import { populateZodSchema } from '@nullix/zod-mongoose';

// Create a schema that expects full User objects instead of IDs
const PopulatedPostSchema = populateZodSchema(PostSchema);

// This will now validate the author object
const validated = PopulatedPostSchema.parse(dataFromApi);

zBuffer(options?)

Helper to create a Zod schema representing a Mongoose Buffer.

  • options: Optional MongooseMeta for this field.

On the server, it also accepts the BSON Binary value returned by Mongoose document.toObject() and parses it as a Node.js Buffer.

import { zBuffer } from '@nullix/zod-mongoose';

const ProductSchema = z.object({
  imageData: zBuffer({ required: true }),
});

GeoJSON helpers

Coming in v3.2: zPoint(options?) and zPolygon(options?) are in the repository but are not available in the published v3.1.1 package yet.

Use zPoint() for a two-dimensional GeoJSON Point and zPolygon() for a Polygon. Coordinates are [longitude, latitude], not [latitude, longitude]. A Polygon has one or more closed rings; each ring needs at least four coordinate pairs, including its repeated first point.

Both helpers validate the object shape with Zod and generate a Mongoose subdocument with the matching type enum and numeric coordinate arrays. The subdocument has no _id by default. For geospatial queries, add a 2dsphere index to the field you query. The optional MongooseMeta argument accepts other field options, such as required.

import {z} from 'zod/v4';
import {toMongooseSchema, zPoint, zPolygon} from '@nullix/zod-mongoose';

const CitySchema = z.object({
  name: z.string(),
  location: zPoint({index: '2dsphere'}),
  boundary: zPolygon(),
});

CitySchema.parse({
  name: 'Example',
  location: {type: 'Point', coordinates: [4.9, 52.3]},
  boundary: {
    type: 'Polygon',
    coordinates: [[[4, 52], [5, 52], [5, 53], [4, 52]]],
  },
});

const mongooseSchema = toMongooseSchema(CitySchema);
// mongooseSchema.indexes() includes [{location: '2dsphere'}, {}].

The helpers check coordinate structure and ring closure; they do not check longitude/latitude ranges, polygon winding, or self-intersection. They are also exported from the browser-safe entry point for shared Zod schemas. Use .optional() for an optional GeoJSON field, or withMongoose() to attach more Mongoose metadata.

genTimestampsSchema(createdAtField?, updatedAtField?)

Returns a plain object (Zod shape) with timestamp fields. This allows for easy spreading into z.object().

  • createdAtField: Name of the "created at" field (default: createdAt).
  • updatedAtField: Name of the "updated at" field (default: updatedAt).

Pass null as a name to disable a specific field.

timestamps.ts
import {z} from 'zod/v4';
import {genTimestampsSchema, toMongooseSchema, withMongoose} from '@nullix/zod-mongoose';

const userSchema = withMongoose(
  z.object({
    ...genTimestampsSchema(),
    name: z.string(),
  }),
  { timestamps: true }
);

const mongooseSchema = toMongooseSchema(userSchema);
// Resulting Mongoose schema will have { timestamps: true } automatically.

Utility Types

@nullix/zod-mongoose provides utility types for document and input inference.

InferDocument<T>

Infers a persisted Mongoose document from a Zod schema, including its generated _id field.

InferInput<T>

Infers raw input accepted by a Zod schema. This is useful for request payloads and preserves input types for Zod coercions and preprocessors.

import type { InferDocument, InferInput } from '@nullix/zod-mongoose';

type UserDocument = InferDocument<typeof UserZodSchema>;
type CreateUserInput = InferInput<typeof UserZodSchema>;

The older InferMongoose, OutputMongoose, and InputMongoose aliases are listed under Migration.