Valibot v1.4: String case transforms, local timestamps, and perf improvements

GitHub profile picture of fabian-hiller

Valibot v1.4 adds four string case transformation actions for converting between common naming conventions, a new validation action for local ISO timestamps without timezone, and a round of performance and compatibility improvements.

Huge thanks to @ksaurav24, @heiwen, @compulim, @ysknsid25, @alaycock-stripe, @IlyaSemenov, and @wszgrcy for their contributions to this release.

String case transformations

Four new transformation actions handle the most common naming convention conversions: toCamelCase, toKebabCase, toPascalCase, and toSnakeCase.

These actions split words on _, -, ASCII whitespace, and case or acronym boundaries, so they work on a wide range of inputs without preprocessing.

import * as v from 'valibot';

const SlugSchema = v.pipe(v.string(), v.toKebabCase());

v.parse(SlugSchema, 'My Blog Post'); // 'my-blog-post'
v.parse(SlugSchema, 'getUserByID'); // 'get-user-by-id'
v.parse(SlugSchema, 'first_name'); // 'first-name'

This is especially useful at API boundaries: normalizing form fields before persisting, or converting incoming JSON keys before passing them to a typed service.

Local ISO timestamps

isoTimestamp requires a timezone designator and isoDateTime only validates hh:mm, leaving a gap for local date-times that include seconds, such as 1995-03-31T00:00:00. The new isoDateTimeSecond action fills that gap.

import * as v from 'valibot';

const EventSchema = v.object({
  startsAt: v.pipe(v.string(), v.isoDateTimeSecond()),
});

v.parse(EventSchema, { startsAt: '1995-03-31T00:00:00' }); // ok
v.parse(EventSchema, { startsAt: '1995-03-31 00:00:00' }); // ok

This is useful for local-only events, schedules, and database columns like PostgreSQL's timestamp (without timezone), where attaching a UTC offset would be incorrect.

Performance improvements

Hot validation paths now allocate fewer objects, and a long-standing RangeError that could occur when spreading very large issue arrays has been fixed. Together, this makes validating large schemas both faster and safer.

TypeScript performance has also improved significantly. The internal types behind object and record schemas — particularly when combined with pipe and the readonly action — have been simplified, making type inference and autocomplete noticeably faster on large codebases.

If you have ever hit a RangeError with a large schema, noticed allocation pressure in a validation hot path, or felt sluggish autocomplete on large object schemas, this release should resolve it.

Compatibility fixes

The build target has been changed to ES2020 so the distributed output stays compatible with environments that lack newer syntax. As part of the same effort, Object.hasOwn (ES2022) was replaced with Object.prototype.hasOwnProperty.call to keep Valibot working on runtimes that have not yet shipped the newer builtin.

The intersect schema no longer mutates input values, so frozen objects and arrays can now be merged without throwing. The creditCard action also rejects Mastercard numbers with invalid lengths instead of accepting them.

What's next?

We will continue to focus on performance, broader runtime compatibility, and refining the developer experience around common validation workflows. If there is a validator, transformation, or guide you would like to see next, let us know on Discord or open a discussion on GitHub.

New to Valibot? Check our quick start guide. Coming from Zod? Check our migration guide.

Edit page

Partners

Thanks to our partners who support the project ideally and financially.

Sponsors

Thanks to our GitHub sponsors who support the project financially.

  • GitHub profile picture of @stefanmaric
  • GitHub profile picture of @vasilii-kovalev
  • GitHub profile picture of @UpwayShop
  • GitHub profile picture of @ruiaraujo012
  • GitHub profile picture of @hyunbinseo
  • GitHub profile picture of @nickytonline
  • GitHub profile picture of @kibertoad
  • GitHub profile picture of @caegdeveloper
  • GitHub profile picture of @Thanaen
  • GitHub profile picture of @bmoyroud
  • GitHub profile picture of @t-lander
  • GitHub profile picture of @dslatkin