Vex

Performance

Benchmarks and performance characteristics

Benchmark Results

All benchmarks run on Bun, measuring operations per second:

OperationVexZodValibotvs Zodvs Valibot
string367M50M50M7.4x7.3x
email128M12M17M11x7.5x
url110M4M5M28x23x
uuid117M16M6M7.3x19x
object (3 fields)18M5M7M3.9x2.7x
object (nested)11M5M5M2x2.1x
array[50]8.5M780K1.4M11x6x
safeParse (valid)15M7M6M2.1x2.5x
safeParse (invalid)44M376K2.6M118x17x

Average: 12x faster than Zod, 6x faster than Valibot

Why is Vex Fast?

1. Pure Functional Design

Validators are constants, not factory functions:

// Vex - zero allocation
str                  // constant
str(email)           // compose constants

// Others - allocates on every call
z.string().email()   // creates new objects
v.string()           // creates new objects

2. No Wrapper Objects

Direct function composition without intermediate objects:

// Vex internals (simplified)
const str = (value) => {
  if (typeof value !== 'string') throw error
  return value
}

// Others create class instances
class StringSchema {
  email() { return new EmailSchema(this) }
  // ...
}

3. Error Path Optimization

Error paths are only computed when validation fails:

// Only allocate on error, not success path
if (!valid) {
  throw new ValidationError(message, path)
}

Running Benchmarks

# Clone the repo
git clone https://github.com/SylphxAI/vex.git
cd vex

# Install dependencies
bun install

# Run benchmarks
bun run bench

Tree-shaking

Vex is fully tree-shakeable:

// Only imports what you use
import { str, num, object } from '@sylphx/vex'

// Bundle size: ~2KB (minified + gzipped)

Compare to Zod which imports the entire library regardless of usage.