Api
Plugins and Hooks
Extend zod-mongoose using Mongoose plugins and a powerful hook system.
Plugins and Hooks
@nullix/zod-mongoose is designed to be highly extensible. You can apply standard Mongoose plugins and use a granular hook system to customize the conversion process.
Mongoose Plugins
You can pass Mongoose plugins directly to toMongooseSchema. This is the recommended way to extend your schemas with third-party or custom Mongoose plugins.
import { z } from 'zod/v4';
import { toMongooseSchema } from '@nullix/zod-mongoose';
import mongooseLeanVirtuals from 'mongoose-lean-virtuals';
const zodSchema = z.object({
title: z.string(),
});
// Apply plugins during conversion
const mongooseSchema = toMongooseSchema(zodSchema, {
plugins: [mongooseLeanVirtuals]
});
// The resulting schema now has the plugin applied
const Post = mongoose.model('Post', mongooseSchema);
const doc = await Post.findOne().lean({ virtuals: true });
Hook System
@nullix/zod-mongoose uses unjs/hookable to provide an extensible conversion process. Developers can register hooks to modify the Mongoose definition at any point of the conversion.
Registering Hooks
import { hooks } from '@nullix/zod-mongoose';
// Modify every string field to be uppercase at the Mongoose level
hooks.hook('converter:node', (context) => {
if (context.type === 'string') {
context.mongooseProp.uppercase = true;
}
});
Advanced Hook: schema:created
Use the schema:created hook to modify the mongoose.Schema instance immediately after it is created.
import { hooks } from '@nullix/zod-mongoose';
hooks.hook('schema:created', ({ schema, zodSchema }) => {
// Add a virtual field to all schemas that have a 'title' field
if ('title' in zodSchema.shape) {
schema.virtual('slug').get(function() {
return this.title.toLowerCase().replace(/ /g, '-');
});
}
});
Available Hooks
The following hook points are available:
converter:before: Called before starting the conversion.converter:start: Called at the start of eachextractMongooseDefcall (recursive).converter:unwrapped: Called after unwrapping a Zod schema and extracting metadata.converter:node: Called for each Zod type node being processed.converter:after: Called after a node's conversion is complete.schema:object:before: Called before processing az.object().schema:object:field: Called for each field in az.object().schema:object:after: Called after processing az.object().schema:array:before: Called before processing an array-like type (z.array(),z.set(),z.tuple()).schema:array:after: Called after processing an array-like type.schema:record:before: Called before processing a record/map type (z.record(),z.map()).schema:record:after: Called after processing a record/map type.schema:union:before: Called before processing az.union()orz.discriminatedUnion().schema:union:after: Called after processing a union.validation:mappers: Called after mapping Zod validations to Mongoose options.schema:created: Called after amongoose.Schemainstance is created.