Arktype feels really nice and promising!
David Blass has a wondeful detailed comparison of Zod and Arktype written here.
My post is smaller in scope, providing a quick comparison of some common tasks in each library.
number
// Zod const num = z.number(); // Arktype const num = type('number');
// Zod const num = z.number(); // Arktype const num = type('number');
object
// Zod const Person = z.object({ name: z.string(), }); // Arktype const Person = type({ name: 'string', });
// Zod const PersonList = z.array(Person); // Arktype const PersonList = type([PersonResult, '[]']); // or const PersonList = arrayOf(PersonResult);
// Zod const Person = z.object({ name: z.string(), }); type Person = z.infer<typeof Person>; // Arktype const Person = type({ name: 'string', }); type Person = typeof PersonList.infer;
// Zod const Person = z.object({ name: z.string(), phoneNumber: z.string().optional(), }); // Arktype const Person = type({ name: 'string', 'phoneNumber?': 'string', });
// Zod const Person = z.object({ name: z.string(), phoneNumber: z.string().default('555-555-5555'), }); // Arktype const FormWithDefault = type({ name: 'string', // unclear if this is idiomatic Arktype phoneNumber: morph('string|undefined', (s) => s ?? '555-555-5555'), });
// Zod const Person = z.record(z.string()); // Arktype const Person = type('string<string>');
// Zod const PrivateOrPublic = z.union([z.literal('private'), z.literal('public')]); // Arktype const PrivateOrPublic = type("'private'|'public'");
number
with min/max length// Zod const PhoneNumber = z.string().min(5).max(20); // Arktype const PhoneNumber = type('5<string<20');
// Zod const PersonZod = z .object({ name: z.string(), }) .transform((person) => ({ ...person, lengthOfName: person.name.length, })); // Arktype: note that in upcoming beta this syntax will change a bit const PersonArktype = type([ { name: 'string', }, '|>', (person) => ({ ...person, lengthOfName: person.name.length }), ]);
// Zod const Positive = z .number() .refine((n) => n > 0, { message: 'Must be positive', }) .brand<'Positive'>(); // Arktype, may change as API changes, see https://github.com/arktypeio/arktype/issues/741 const Positive = type('number>0' as Infer<Brand<number, 'Positive'>>); // where Infer is a helper type from Arktype // where Brand is the helper type declare const brand: unique symbol; type Brand<T, U> = T & { [brand]: U };