npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

iron-enum-zod

v1.0.1

Published

A lightweight helper library to create [`iron-enum`](https://www.npmjs.com/package/iron-enum) factories and `zod` schemas from a single definition.

Readme

🦾 Iron Enum Zod

A lightweight helper library to create iron-enum factories and zod schemas from a single definition.

iron-enum-zod provides a createZodEnum function that acts as a single source of truth, generating both your type-safe IronEnum and a zod schema for runtime validation.

The Problem

iron-enum is type-safe, but its types are erased at compile-time. zod provides runtime validation, but you have to define your schemas separately, leading to duplicated logic.

// Before: Duplicated Definitions

import { z } from 'zod';
import { IronEnum } from 'iron-enum';

// 1. Zod definition for runtime
const StatusSchema = z.union([
  z.object({ Loading: z.undefined() }),
  z.object({ Ready: z.object({ finishedAt: z.date() }) }),
]);

// 2. IronEnum definition for compile-time
const Status = IronEnum<{
  Loading: undefined;
  Ready: { finishedAt: Date };
}>();

This is hard to maintain.

The Solution

iron-enum-zod lets you define your payloads once with Zod and get everything you need.

// After: Single Source of Truth
import { z } from 'zod';
import { createZodEnum } from 'iron-enum-zod';

// 1. Define payloads ONCE
const StatusPayloads = {
  Loading: z.undefined(),
  Ready: z.object({ finishedAt: z.coerce.date() }),
  Error: z.object({ message: z.string() }),
};

// 2. Create the enum and schema
const Status = createZodEnum(StatusPayloads);

// 3. You get a fully-featured IronEnum factory...
const loading = Status.self.Loading();

// 4. ...AND a powerful parser.
const result = Status.parse({ tag: "Ready", data: { finishedAt: "2025-10-25" } });

// you can also directly access the zod schema
const zodSchema = Status.schema;

Installation

You need iron-enum, zod, and iron-enum-zod.

npm install iron-enum zod iron-enum-zod
# or
yarn add iron-enum zod iron-enum-zod
# or
pnpm add iron-enum zod iron-enum-zod

Quick Start

import { z } from 'zod';
import { createZodEnum } from 'iron-enum-zod';

// 1. Define your payload schemas
const StatusPayloads = {
  Loading: z.undefined(),
  Ready: z.object({ finishedAt: z.coerce.date() }),
  Error: z.object({ message: z.string(), code: z.number().optional() }),
};

// 2. Create your ZodEnum factory
const Status = createZodEnum(StatusPayloads);

// --- Using the Enum ---

// You can create instances just like a normal IronEnum
// using the `.self` property.
const ready = Status.self.Ready({ finishedAt: new Date() });

const message = ready.match({
  Loading: () => "Still loading...",
  Ready: ({ payload }) => `Done at ${payload.finishedAt.toISOString()}`,
  Error: ({ payload }) => `Failed: ${payload.message}`,
  _: (self) => `Unknown state: ${self.key()}`,
});

// --- Using the Parsers ---

// An example API response
const apiInput = { tag: "Error", data: { message: "Network failed", code: 222 } };

// Use .safeParse() to get a Result<Status, ZodError>
const result = Status.safeParse(apiInput);

result.match({
  Ok: (statusInstance) => {
    // statusInstance is a valid IronEnum: { tag: "Error", ... }
    console.log(`Parsed status: ${statusInstance.key()}`);
  },
  Err: (zodError) => {
    // zodError is a ZodError instance
    console.error("Validation failed:", zodError.issues);
  }
});

// Or use .parse() which throws on failure
try {
  const status = Status.parse({ Loading: undefined });
  console.log("Parsed!", status.tag); // Parsed! Loading
} catch (e) {
  console.error("Failed to parse", e);
}

API Reference

The createZodEnum(payloads) function returns an object with the following properties:

self

The core IronEnumInstance factory. You use this to create new enum variants.

const loading = Status.self.Loading();
const error = Status.self.Error({ message: "..." });

schema

The raw z.ZodType schema. This is useful for embedding your enum schema inside other Zod schemas.

It validates the toJSON()/_.parse() format (e.g., { tag: ..., data: ... }).

const UserSchema = z.object({
  id: z.string(),
  status: Status.schema, // Embed the enum schema
});

const user = UserSchema.parse({
  id: "user-123",
  status: { tag: "Ready", data: { finishedAt: new Date() } }
});

parse(input, params?)

Parses and validates an unknown input. If validation succeeds, it returns a fully-formed IronEnum instance. If validation fails, it throws a ZodError.

// This works
const status = Status.parse({ tag: "Ready", data: { finishedAt: new Date() } });

// This throws
const status = Status.parse({ tag: "Ready", data: { finishedAt: "Not a date" } });

safeParse(input, params?)

Parses and validates an unknown input. It does not throw. Instead, it returns an IronEnum Result:

  • Ok(IronEnum) on success.
  • Err(ZodError) on failure.

This is the recommended way to handle untrusted data.

const result = Status.safeParse({ tag: "Error", data: { message: 123 } }); // 'message' is wrong type

if (result.isErr()) {
  console.error(result.data.issues); // Safely access the ZodError
}

MIT © 2025 Scott Lott

Made with ❤️ by a developer who misses Rust's enums in TypeScript