zod nativeenum

Zod nativeEnum in Zod 4

Migrate Zod 3 nativeEnum usage to Zod 4 z.enum, validate TypeScript enums and enum-like objects, and avoid common enum value mistakes.

Open the JSON to Zod converter

Quick answer: what replaced z.nativeEnum?

In Zod 4, use `z.enum()` for string arrays, enum-like objects, and externally declared TypeScript enums. `z.nativeEnum()` was the Zod 3 API; new Zod 4 code should prefer `z.enum()`.

String enum with z.enum

For most APIs and forms, a string literal enum is clearer than a TypeScript enum. Pass values inline or use `as const` so TypeScript keeps the exact literal union.

const RoleSchema = z.enum(["admin", "editor", "viewer"]);

type Role = z.infer<typeof RoleSchema>;

RoleSchema.parse("admin");

Use as const for reusable arrays

If enum values live in a variable, preserve the literal tuple with `as const`. Without it, TypeScript may widen the array to `string[]` and lose the exact value union.

const statusValues = ["draft", "review", "published"] as const;

const StatusSchema = z.enum(statusValues);

type Status = z.infer<typeof StatusSchema>;

Migrate z.nativeEnum to z.enum

When migrating older Zod 3 code, change the schema constructor and keep tests around the accepted runtime values. Numeric enums and string enums can behave differently, so test the actual values your API sends.

enum Status {
  Draft = "draft",
  Published = "published",
}

// Zod 3 style:
// const StatusSchema = z.nativeEnum(Status);

// Zod 4 style:
const StatusSchema = z.enum(Status);

Enum values vs enum keys

A common nativeEnum mistake is expecting Zod to validate enum member names when the API sends enum values, or the reverse. Decide whether the payload contains `Draft` or `draft`, then model that exact value set.

const ApiStatusSchema = z.enum(["draft", "published"]);

ApiStatusSchema.safeParse("draft"); // success
ApiStatusSchema.safeParse("Draft"); // failure

Exclude or extract enum values

When a form or API route should accept only part of an enum, create a narrower schema with `.exclude()` or `.extract()` instead of adding a vague custom refinement.

const WorkflowStatus = z.enum(["draft", "review", "published", "archived"]);

const EditableStatus = WorkflowStatus.exclude(["archived"]);
const PublicStatus = WorkflowStatus.extract(["published"]);

Generated schemas and enum review

JSON samples can reveal a current enum value, but they cannot prove every allowed value. After using a generator, replace broad strings with explicit `z.enum()` values from product docs, API contracts, or database enums.

Zod enum checklist

Enum bugs are usually value drift bugs. Keep the schema close to the system that owns the allowed values and test the values sent by real payloads.

  • Use `z.enum()` for new Zod 4 code.
  • Prefer string literal values for API payloads and UI forms.
  • Use `.exclude()` or `.extract()` for subsets.
  • Add tests for lowercase, uppercase, unknown, and deprecated values.

Zod enum migration map

PatternZod 4 approachWhy it matters
String literal choices`z.enum(["draft", "published"])`Best inference when the values are declared inline or `as const`.
Enum-like object`z.enum(Status)` with an object literalKeeps runtime values and inferred values aligned.
TypeScript enum`z.enum(MyEnum)`Zod 4 supports externally declared TypeScript enums through z.enum.
Old Zod 3 nativeEnumReplace `z.nativeEnum()` with `z.enum()`The old API is deprecated, so new docs and examples should use z.enum.

Use FrameworkKit to generate the starter code, then review the output before shipping it in production.

Generate with the JSON to Zod schema generator

Zod validation resources

JSON to Zod converter

Convert sample payloads into copy-ready Zod schemas and inferred TypeScript types in the browser.

JSON to Zod schema examples

Open realistic API and product payload examples before adapting the JSON to Zod schema output.

TypeScript to Zod Converter

Convert TypeScript interfaces and type aliases into Zod schemas when the source shape already lives in code.

Zod to JSON Schema Converter

Use the canonical online converter when an existing Zod schema needs JSON Schema, AJV, or OpenAPI output.

Validate API responses with Zod

Validate API responses, request bodies, and fetch boundaries with Zod schemas in TypeScript.

Zod parse vs safeParse

Choose between parse, safeParse, parseAsync, and safeParseAsync for TypeScript validation flows.

Zod safeParse

Validate unknown data without throwing, narrow the result type, and format safeParse errors.

Zod safeParse error messages

Format safeParse failures, field errors, and API validation responses in TypeScript.

Zod refine vs superRefine

Add custom validation, async checks, and field-level error paths after generating a starter schema.

Use JSON to Zod for form validation

Start from a submitted form payload, then add business rules such as email, length, and enum checks.

Zod to JSON Schema for OpenAPI

Publish Zod API schemas as OpenAPI-compatible contracts when teams need portable documentation.

Zod vs JSON Schema

Choose between TypeScript-first runtime validation and portable schema contracts.

Zod vs Yup vs Valibot

Compare TypeScript validation libraries for API boundaries, forms, server actions, and bundle tradeoffs.

FAQ

Is z.nativeEnum deprecated in Zod 4?

Yes. Zod 4 documentation directs developers to use z.enum for externally declared TypeScript enums instead of z.nativeEnum.

Can z.enum accept a TypeScript enum?

Yes. Zod 4 z.enum can accept an externally declared TypeScript enum, but you should test the actual runtime values your API sends.

Should I use TypeScript enum or string literals with Zod?

For most API and form validation, string literal arrays are easier to inspect and serialize. Use TypeScript enums only when the codebase already owns them.

How do I validate only part of a Zod enum?

Use `.exclude()` to remove values or `.extract()` to keep selected values. This keeps the accepted values explicit.

Related tools