neovim-mark@2x
Bun Logo

Arktype

Typescript's 1:1 validator, optimized from editor to runtime

Set Sail

What awaits

Unparalleled DX

Type syntax you already know with safety and completions unlike anything you've ever seen
// @noErrors
import { type } from "arktype"
// prettier-ignore
// ---cut---
const user = type({
	name: "string",
	platform: "'android' | 'ios'",
	"version?": "number | s"
	//                     ^|
})

Faster... everything

100x faster than Zod at runtime with editor performance that will remind you how autocomplete is supposed to feel
Object Validation, Node v22.2.0 (source)
ArkType (15 nanoseconds)
  Zod (1374 nanoseconds)

Clarity and Concision

Definitions are half as long, type errors are twice as readable, and hovers tell you just what really matters
// @errors: 2322
import { type } from "arktype"
// this file is written in JS so that it can include a syntax error
// without creating a type error while still displaying the error in twoslash
// ---cut---
// hover me
const user = type({
	name: "string",
	platform: "'android' | 'ios'",
	"versions?": "number | string)[]"
})

Better Errors

Deeply customizable messages with great defaults
import { type, type ArkErrors } from "arktype"

const user = type({
	name: "string",
	platform: "'android' | 'ios'",
	"versions?": "(number | string)[]"
})

interface RuntimeErrors extends ArkErrors {
	/**platform must be "android" or "ios" (was "enigma")
versions[2] must be a number or a string (was bigint)*/
	summary: string
}

const narrowMessage = (e: ArkErrors): e is RuntimeErrors => true

// ---cut---
const out = user({
	name: "Alan Turing",
	platform: "enigma",
	versions: [0, "1", 0n]
})

if (out instanceof type.errors) {
	// ---cut-start---
	if (!narrowMessage(out)) throw new Error()
	// ---cut-end---
	// hover summary to see validation errors
	console.error(out.summary)
}

Deep Introspectability

ArkType uses set theory to understand and expose the relationships between your types at runtime the way TypeScript does at compile time
import { type } from "arktype"

const user = type({
	name: "string",
	device: {
		platform: "'android' | 'ios'",
		"version?": "number | string"
	}
})

// ---cut---
user.extends("object") // true
user.extends("string") // false
// true (string is narrower than unknown)
user.extends({
	name: "unknown"
})
// false (string is wider than "Alan")
user.extends({
	name: "'Alan'"
})

Intrinsic Optimization

Every schema is internally normalized and reduced to its purest and fastest representation
import { type } from "arktype"
// prettier-ignore
// ---cut---
// all unions are optimally discriminated
// even if multiple/nested paths are needed
const account = type({
	kind: "'admin'",
	"powers?": "string[]"
}).or({
	kind: "'superadmin'",
	"superpowers?": "string[]"
}).or({
	kind: "'pleb'"
})