Valibot generator
Generate Valibot schemas from OpenAPI
@skmtc/gen-valibot
OpenAPI to Valibot schema generator for Skmtc.
Generate type-safe Valibot validation schemas from your OpenAPI specifications. Valibot is a modular, lightweight schema library with excellent TypeScript support and tree-shaking capabilities.
Installation
Install Deno
# On MacOS/Linux
curl -fsSL https://deno.land/install.sh | sh
# On Windows
irm https://deno.land/install.ps1 | iex
Install Skmtc
deno install -g -A --unstable-worker-options jsr:@skmtc/cli@0.0.388 -n skmtc -f
Create project and generate artifacts using TUI (recommended)
# Create project then Generate artifacts
skmtc
Create project and generate artifacts using CLI
# Create project
skmtc init <project name>
# Install Valibot generator
skmtc install @skmtc/gen-valibot <project name>
# Bundle generator code
skmtc bundle <project name>
# Generate artifacts from OpenAPI schema
skmtc generate <project name> <path or url to openapi schema>
Usage Examples
Basic Types
| Input (OpenAPI Schema) | Valibot Schema |
|---|---|
json<br>{<br> "components": {<br> "schemas": {<br> "User": {<br> "type": "object",<br> "properties": {<br> "id": { "type": "string" },<br> "age": { "type": "number" },<br> "isActive": { "type": "boolean" }<br> },<br> "required": ["id", "age"]<br> }<br> }<br> }<br>}<br> |
typescript<br>import * as v from "valibot"<br>export const User = v.object({<br> id: v.string(),<br> age: v.number(),<br> isActive: v.optional(v.boolean())<br>})<br> |
Enums and Literals
| Input (OpenAPI Schema) | Valibot Schema |
|---|---|
json<br>{<br> "Status": {<br> "type": "string",<br> "enum": ["active", "inactive", "pending"]<br> },<br> "Role": {<br> "type": "string",<br> "enum": ["admin"]<br> }<br>}<br> |
typescript<br>export const Status = v.picklist(["active", "inactive", "pending"])<br>export const Role = v.literal("admin")<br> |
Arrays and Nested Objects
| Input (OpenAPI Schema) | Valibot Schema |
|---|---|
json<br>{<br> "Team": {<br> "type": "object",<br> "properties": {<br> "name": { "type": "string" },<br> "members": {<br> "type": "array",<br> "items": {<br> "type": "object",<br> "properties": {<br> "id": { "type": "string" },<br> "role": { "type": "string" }<br> },<br> "required": ["id", "role"]<br> }<br> }<br> },<br> "required": ["name", "members"]<br> }<br>}<br> |
typescript<br>export const Team = v.object({<br> name: v.string(),<br> members: v.array(v.object({<br> id: v.string(),<br> role: v.string()<br> }))<br>})<br> |
Nullable and Optional Fields
| Input (OpenAPI Schema) | Valibot Schema |
|---|---|
json<br>{<br> "Profile": {<br> "type": "object",<br> "properties": {<br> "bio": {<br> "type": "string",<br> "nullable": true<br> },<br> "website": { "type": "string" }<br> },<br> "required": ["bio"]<br> }<br>}<br> |
typescript<br>export const Profile = v.object({<br> bio: v.nullable(v.string()),<br> website: v.optional(v.string())<br>})<br> |
Union Types
| Input (OpenAPI Schema) | Valibot Schema |
|---|---|
json<br>{<br> "Pet": {<br> "oneOf": [<br> {<br> "type": "object",<br> "properties": {<br> "type": { "type": "string", "enum": ["cat"] },<br> "meow": { "type": "boolean" }<br> },<br> "required": ["type", "meow"]<br> },<br> {<br> "type": "object",<br> "properties": {<br> "type": { "type": "string", "enum": ["dog"] },<br> "bark": { "type": "boolean" }<br> },<br> "required": ["type", "bark"]<br> }<br> ]<br> }<br>}<br> |
typescript<br>export const Pet = v.union([<br> v.object({<br> type: v.literal("cat"),<br> meow: v.boolean()<br> }),<br> v.object({<br> type: v.literal("dog"),<br> bark: v.boolean()<br> })<br>])<br> |
String Formats
| Input (OpenAPI Schema) | Valibot Schema |
|---|---|
json<br>{<br> "Event": {<br> "type": "object",<br> "properties": {<br> "createdAt": {<br> "type": "string",<br> "format": "date-time"<br> }<br> },<br> "required": ["createdAt"]<br> }<br>}<br> |
typescript<br>export const Event = v.object({<br> createdAt: v.pipe(v.string(), v.isoDateTime())<br>})<br> |
Additional Properties
| Input (OpenAPI Schema) | Valibot Schema |
|---|---|
json<br>{<br> "Metadata": {<br> "type": "object",<br> "additionalProperties": { "type": "string" }<br> }<br>}<br> |
typescript<br>export const Metadata = v.record(v.string(), v.string())<br> |
With both properties and additionalProperties:
| Input (OpenAPI Schema) | Valibot Schema |
|---|---|
json<br>{<br> "Config": {<br> "type": "object",<br> "properties": {<br> "id": { "type": "string" }<br> },<br> "required": ["id"],<br> "additionalProperties": { "type": "number" }<br> }<br>}<br> |
typescript<br>export const Config = v.intersect([<br> v.object({ id: v.string() }),<br> v.record(v.string(), v.number())<br>])<br> |
Supported Features
- Primitive types: string, number, integer, boolean
- Complex types: object, array, union (oneOf/anyOf)
- Modifiers: nullable, optional
- Enums: Single values (literal) and multiple values (picklist)
- String formats: date-time (isoDateTime)
- Integer validation: Uses
v.pipe(v.number(), v.integer()) - References: Schema references via
$ref - Additional properties: Record types and intersections
- Nested structures: Deeply nested objects and arrays
Testing
Run tests for this generator:
cd gen-valibot && deno task test
Or with coverage:
deno task test:coverage
License
MIT.
@skmtc/gen-valibot
MIT License
Last updated: Nov 13, 2025