v3.3.1
Playground
API Reference

Conversion Mapping

How Zod types and validations are mapped to Mongoose.

Conversion Mapping

@nullix/zod-mongoose maps supported Zod types and checks to Mongoose SchemaType options. Zod transforms are parsed during validation, but their output is not assigned to the stored document; see Validate Documents.

For a stored date, use z.date() or z.coerce.date(). For an ISO string you want to keep as a string, use z.iso.datetime() or z.iso.date(). Avoid z.string().datetime() and z.string().date() for persisted fields: they map to Mongoose Date, then fail the default Zod validation because Mongoose casts the value to a Date while Zod expects a string.

Automatic Validation Mapping

The following Zod checks are directly converted to Mongoose SchemaType options:

Zod CheckMongoose OptionTarget Types
.min(n)minlength: nz.string()
.max(n)maxlength: nz.string()
.length(n)minlength: n, maxlength: nz.string()
.regex(re)match: rez.string()
.trim()trim: truez.string()
.toLowerCase()lowercase: truez.string()
.toUpperCase()uppercase: truez.string()
.min(n) / .positive()min: nz.number(), z.date()
.max(n) / .negative()max: nz.number(), z.date()
.uuid()UUID format validation; normally Stringz.string()
.datetime()type: Date; see date caveat abovez.string()
.date()type: Date; see date caveat abovez.string()
.time()type: Stringz.string()

Type Conversion Table

The following table shows how Zod types are mapped to Mongoose types by default.

Zod TypeMongoose TypeNotes
z.string()StringRequired by default unless .optional() is used.
z.uuid() / z.string().uuid()String by defaultUUID format is still checked by Zod. A configured global Mongoose instance may select its native UUID type.
z.iso.datetime() / z.iso.date()StringKeeps the ISO text and passes default post-validation.
z.string().datetime() / z.string().date()DateMongoose casts to Date, so default post-validation fails; use one of the alternatives above.
z.number()Number
z.boolean()Boolean
z.date()Date
z.bigint()BigIntFallback to Number if BigInt is not supported. Use withMongoose with type: 'Long' for 64-bit integers.
z.enum()StringIncludes Mongoose enum validation.
z.nativeEnum()StringIncludes Mongoose enum validation.
z.string().trim()StringAutomatically sets trim: true.
z.string().toLowerCase()StringAutomatically sets lowercase: true.
z.string().min(5)StringAutomatically sets minlength: 5.
z.array()[]Mapped to a Mongoose array of the inner type.
z.set()[]Mapped to a Mongoose array of the value type.
z.tuple()[]Mapped to a Mongoose array of the first item's type.
z.record()ObjectMapped to a Mongoose nested object (POJO) with dynamic keys.
z.map()MapMapped to a Mongoose Map with of type.
z.object()SubdocumentUnknown keys are stripped. Nested objects have their own _id by default. See Nested Object IDs.
z.strictObject()Subdocument with strict: 'throw'Rejects unknown keys; Mongoose-generated IDs and version keys are excluded from Zod document validation unless declared.
z.looseObject()Subdocument with strict: falsePreserves unknown keys.
.catchall(valueSchema)Subdocument with strict: falsePreserves unknown keys and validates values in the document validation hook. Dynamic keys do not get individual Mongoose paths.
.required() / exactOptional() fieldsUnderlying field typeRequired fields use Mongoose required where compatible; exact optional fields reject explicit undefined on document assignment.
z.intersection()SubdocumentMerges the definitions of both branches into a single subschema.
z.union()Schema.Types.Union (primitives) or Nested Object (objects)Mapped to Union for primitives, merged into an object for z.object() unions. Others fallback to Mixed.
z.xor()mongoose.Schema.Types.MixedNon-inclusive union. Maps to Mixed with a custom Zod-based validator to enforce mutual exclusivity.
z.discriminatedUnion()Mongoose DiscriminatorMaps to native Mongoose discriminators. Common fields are automatically moved to the base schema.
zObjectId()mongoose.Schema.Types.ObjectIdSpecialized helper for ObjectIds. By default, it is omitted from the generated Mongoose schema to let Mongoose handle its auto-generation.
zBuffer()mongoose.Schema.Types.BufferSpecialized helper for Buffers.
zPoint() (coming in v3.2)GeoJSON Point subdocumentTwo numeric coordinates; no nested _id by default. See GeoJSON helpers.
zPolygon() (coming in v3.2)GeoJSON Polygon subdocumentOne or more closed rings; no nested _id by default.
zRef()mongoose.Schema.Types.ObjectIdHelper for fields that can be either an ObjectId (unpopulated) or a full object (populated). During Zod validation, it accepts both but always outputs an ObjectId.
z.instanceof(Buffer)mongoose.Schema.Types.Buffer
z.instanceof(ObjectId)mongoose.Schema.Types.ObjectId
z.literal()String / Number / BooleanMapped to the literal's type with a Mongoose enum constraint.
z.any() / z.unknown()mongoose.Schema.Types.MixedFallback for unhandled types.

Unhandled and Unsupported Zod Types

The following Zod types are currently not explicitly handled or are unsupported by nature and will fall back to Mongoose.Schema.Types.Mixed unless a custom type is provided via withMongoose.

Zod TypeCurrent StatusRecommended Alternative
z.readonly()Base TypeAutomatically unwrapped, applies readOnly: true metadata.
z.promise()UnsupportedNot applicable for database schemas
z.function()UnsupportedNot applicable for database schemas
z.void() / z.never()Unsupported

Note: Types like z.branded(), z.readonly(), z.pipeline(), z.preprocess(), and z.transform() are automatically unwrapped to their underlying base type during conversion.

See Object Modes and Unknown Keys for nested objects, option overrides, and query-update caveats.