ArkType is TypeScript's 1:1 validator, optimized from editor to runtime. It parses TypeScript-like string syntax at runtime — this is unique among validation libraries.
pnpm i && pnpm build # install and build all packages
pnpm prChecks # lint + build + test (run before PRs)
pnpm testTyped --skipTypes # run tests without type checkingark/type/— main validation library (arktypeon npm)ark/schema/— schema layer (constraint nodes, refinements, scopes)ark/util/— shared utilitiesark/docs/— documentation site (Fumadocs/Next.js)ark/json-schema/— JSON Schema conversionark/regex/— ArkRegex type-safe regexark/attest/— custom assertion/test libraryark/fast-check/— property testing integration
String keywords follow typescriptType.constraint.subconstraint:
string.email,string.uuid,string.url,string.hexnumber.integer,number.safe,number.epoch- Morphs:
string.trim,string.json.parse,string.date.parse
Adding a regex string validator:
const myValidator = regexStringNode(/^pattern$/, "description")Register in Scope.module() in ark/type/keywords/string.ts and add to the namespace $ type.
Adding a number keyword:
Use rootSchema() with domain, min/max, or predicate constraints. See number.safe in ark/type/keywords/number.ts.
- Tabs, no semicolons, no trailing commas (
prettierenforced) experimentalTernaries: true—?at end of line,:on next linearrowParens: "avoid"—x => xnot(x) => x- Tests use
attest(custom lib) with.snap()for snapshots
// optional keys — append ? to the key name
type({ "name?": "string" })
// arrays — use .array(), NOT type([Schema])
Schema.array()
// records — use index signature syntax
type({ "[string]": ValueSchema })
// type inference
type User = typeof UserSchema.infer
// error handling
const out = Schema(data)
if (out instanceof type.errors) {
console.error(out.summary)
}
// three syntax kinds (equivalent):
type("string | number") // string expression
type(["string", "|", "number"]) // tuple expression
type("string").or("number") // chainedtype([X])creates a 1-element tuple, not an array — useX.array()"string | undefined"for optional — use"key?": "string"instead"Record<string, T>"doesn't work — usetype({ "[string]": T })safeParse()doesn't exist — call the type directly:const out = Schema(data)regexStringNode()patterns must be anchored with^/$