💎 Zod 4 is now stable!  Read the announcement.
Zod logo

Zod Mini

Nota — La documentación para Zod Mini está intercalada con la documentación regular de Zod a través de bloques de código con pestañas. Esta página está diseñada para explicar por qué existe Zod Mini, cuándo usarla y algunas diferencias clave con Zod regular.

La variante Zod Mini se introdujo con el lanzamiento de Zod 4. Para probarla:

npm install zod@^4.0.0

Para importarla:

import * as z from "zod/mini";

Zod Mini implementa exactamente la misma funcionalidad que zod, pero usando una API funcional, apta para tree-shaking. Si vienes de zod, esto significa que generalmente usarás funciones en lugar de métodos.

// Zod regular
const mySchema = z.string().optional().nullable();
 
// Zod Mini
const mySchema = z.nullable(z.optional(z.string()));

Tree-shaking

Tree-shaking es una técnica utilizada por los empaquetadores modernos para eliminar el código no utilizado del paquete final. También se conoce como eliminación de código muerto.

En Zod regular, los esquemas proporcionan una variedad de métodos de conveniencia para realizar algunas operaciones comunes (por ejemplo, .min() en esquemas de cadena). Los empaquetadores generalmente no pueden eliminar ("treeshake") implementaciones de métodos no utilizados de su paquete, pero pueden eliminar funciones de nivel superior no utilizadas. Como tal, la API de Zod Mini utiliza más funciones que métodos.

// Zod regular
z.string().min(5).max(10).trim()
 
// Zod Mini
z.string().check(z.minLength(5), z.maxLength(10), z.trim());

Para dar una idea general sobre la reducción del tamaño del paquete, considera este script simple:

z.boolean().parse(true)

Empaquetar esto con Zod y Zod Mini resulta en los siguientes tamaños de paquete. Zod Mini resulta en una reducción del 64%.

PaqueteTamaño del paquete (gzip)
Zod Mini2.12kb
Zod5.91kb

Con un esquema marginalmente más complejo que involucra tipos de objetos:

const schema = z.object({ a: z.string(), b: z.number(), c: z.boolean() });
 
schema.parse({
  a: "asdf",
  b: 123,
  c: true,
});
PaqueteTamaño del paquete (gzip)
Zod Mini4.0kb
Zod13.1kb

Esto te da una idea de los tamaños de paquete involucrados. Mira de cerca estos números y ejecuta tus propios benchmarks para determinar si usar Zod Mini vale la pena para tu caso de uso.

Cuándo (no) usar Zod Mini

En general, probablemente deberías usar Zod regular a menos que tengas restricciones poco comunes en torno al tamaño del paquete. Muchos desarrolladores sobreestiman masivamente la importancia del tamaño del paquete para el rendimiento de la aplicación. En la práctica, el tamaño del paquete a la escala de Zod (5-10kb típicamente) es solo una preocupación significativa cuando se optimizan paquetes de front-end para una base de usuarios con conexiones de red móvil lentas en áreas rurales o en desarrollo.

Repasemos algunas consideraciones:

DX

La API de Zod Mini es más verbosa y menos descubrible. Los métodos en la API de Zod son mucho más fáciles de descubrir y autocompletar a través de Intellisense que las funciones de nivel superior en Zod Mini. No es posible construir rápidamente un esquema con API encadenadas. (Hablando como el creador de Zod: pasé mucho tiempo diseñando la API de Zod Mini para que sea lo más ergonómica posible, pero todavía tengo una fuerte preferencia por la API estándar de Zod).

Desarrollo backend

Si estás usando Zod en el backend, el tamaño del paquete a la escala de Zod no es significativo. Esto es cierto incluso en entornos con recursos limitados como Lambda. Esta publicación realiza benchmarks de tiempos de arranque en frío con paquetes de varios tamaños. Aquí hay un subconjunto de los resultados:

Tamaño del paqueteTiempo de arranque en frío de Lambda
1kb171ms
17kb (tamaño de Zod no Mini gzip)171.6ms (interpolado)
128kb176ms
256kb182ms
512kb279ms
1mb557ms

El tiempo mínimo de arranque en frío para un paquete insignificante de 1kb es 171ms. El siguiente tamaño de paquete probado es 128kb, que agregó solo 5ms. Cuando se comprime con gzip, el tamaño del paquete para la totalidad de Zod regular es aproximadamente 17kb, lo que correspondería a un aumento de 0.6ms en el tiempo de inicio.

Velocidad de Internet

Generalmente, el tiempo de ida y vuelta al servidor (100-200ms) empequeñecerá el tiempo requerido para descargar 10kb adicionales. Solo en conexiones 3G lentas (sub-1Mbps), el tiempo de descarga para 10kb adicionales se vuelve más significativo. Si no estás optimizando específicamente para usuarios en áreas rurales o en desarrollo, es probable que tu tiempo esté mejor invertido optimizando otra cosa.

ZodMiniType

Todos los esquemas de Zod Mini extienden la clase base z.ZodMiniType, que a su vez extiende z.core.$ZodType de zod/v4/core. Si bien esta clase implementa mucho menos métodos que ZodType en zod, permanecen algunos métodos particularmente útiles.

.parse

Este es obvio. Todos los esquemas de Zod Mini implementan los mismos métodos de análisis que zod.

import * as z from "zod/mini"
 
const mySchema = z.string();
 
mySchema.parse('asdf')
await mySchema.parseAsync('asdf')
mySchema.safeParse('asdf')
await mySchema.safeParseAsync('asdf')

.check()

En Zod regular hay métodos dedicados en subclases de esquema para realizar comprobaciones comunes:

import * as z from "zod";
 
z.string()
  .min(5)
  .max(10)
  .refine(val => val.includes("@"))
  .trim()

En Zod Mini, tales métodos no están implementados. En su lugar, pasas estas comprobaciones a los esquemas usando el método .check():

import * as z from "zod/mini"
 
z.string().check(
  z.minLength(5), 
  z.maxLength(10),
  z.refine(val => val.includes("@")),
  z.trim()
);

Se implementan las siguientes comprobaciones. Algunas de estas comprobaciones solo se aplican a esquemas de ciertos tipos (por ejemplo, cadenas o números). Las API son todas seguras en cuanto a tipos; TypeScript no te permitirá agregar una comprobación no compatible a tu esquema.

z.lt(value);
z.lte(value); // alias: z.maximum()
z.gt(value);
z.gte(value); // alias: z.minimum()
z.positive();
z.negative();
z.nonpositive();
z.nonnegative();
z.multipleOf(value);
z.maxSize(value);
z.minSize(value);
z.size(value);
z.maxLength(value);
z.minLength(value);
z.length(value);
z.regex(regex);
z.lowercase();
z.uppercase();
z.includes(value);
z.startsWith(value);
z.endsWith(value);
z.property(key, schema);
z.mime(value);
 
// comprobaciones personalizadas
z.refine()
z.check()   // reemplaza .superRefine()
 
// mutaciones (estas no cambian los tipos inferidos)
z.overwrite(value => newValue);
z.normalize();
z.trim();
z.toLowerCase();
z.toUpperCase();

.register()

Para registrar un esquema en un registro.

const myReg = z.registry<{title: string}>();
 
z.string().register(myReg, { title: "My cool string schema" });

.brand()

Para marcar (brand) un esquema. Consulta la documentación de Tipos marcados para obtener más información.

import * as z from "zod/mini"
 
const USD = z.string().brand("USD");

.clone(def)

Devuelve un clon idéntico del esquema actual utilizando el def proporcionado.

const mySchema = z.string()
 
mySchema.clone(mySchema._zod.def);

Sin configuración regional predeterminada

Mientras que Zod regular carga automáticamente la configuración regional en inglés (en), Zod Mini no lo hace. Esto reduce el tamaño del paquete en escenarios donde los mensajes de error son innecesarios, localizados a un idioma que no sea inglés o personalizados de otra manera.

Esto significa que, por defecto, la propiedad message de todos los problemas simplemente leerá "Invalid input". Para cargar la configuración regional en inglés:

import * as z from "zod/mini"
 
z.config(z.locales.en());

Consulta la documentación de Configuraciones regionales para más información sobre la localización.

On this page