npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

unplugin-valibot-to-json-schema

v0.1.3

Published

Transform Valibot schemas to JSON Schema at build time

Readme

unplugin-valibot-to-json-schema

NPM version Tests stability

Experimental: This plugin is still being hardened. APIs and behavior may change between minor versions.

A build-time transformer that replaces toJsonSchema(...) calls with the serialized JSON Schema output, so schemas never ship to the client or execute at runtime.

Why?

JSON Schema is a language-independent serialization of your Valibot schemas. It lets you share validation rules across the stack, feed them to generic validators, form builders, AI tools, and LED emitting front-end libraries — without shipping the schema-building code or paying the runtime cost of generating the schema.

Runtime savings

Instead of shipping @valibot/to-json-schema (and executing it on every schema definition), the plugin bakes the schema into a plain JSON object at build time:

| Approach | Runtime work | | ------------------------------------- | -------------------------------- | | toJsonSchema(schema) at runtime | Executes the schema on every load | | unplugin-valibot-to-json-schema | Sends zero calls to toJsonSchema |

This plugin automatically finds your toJsonSchema(...) calls, statically evaluates the referenced Valibot schemas, and replaces the call with the final JSON object. No runtime dependency on @valibot/to-json-schema.

Features

  • Replaces every toJsonSchema(...) call with its serialized JSON Schema output
  • Statically evaluates schemas from local constants and imported modules
  • Handles inline v.object({...}) schemas and schemas backed by imported bindings
  • Supports the toJsonSchema(schema, config) config object (e.g. target: 'draft-2020-12')
  • Removes the now-unused @valibot/to-json-schema import
  • Emits source maps for debugging

Install

npm install unplugin-valibot-to-json-schema

Usage

Vite

// vite.config.ts
import valibotToJsonSchema from "unplugin-valibot-to-json-schema/vite";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [valibotToJsonSchema()],
});

Rollup

// rollup.config.js
import valibotToJsonSchema from "unplugin-valibot-to-json-schema/rollup";

export default {
  plugins: [valibotToJsonSchema()],
};

Webpack

// webpack.config.js
module.exports = {
  plugins: [require("unplugin-valibot-to-json-schema/webpack")()],
};

Nuxt

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ["unplugin-valibot-to-json-schema/nuxt"],
});

esbuild

// esbuild.config.js
import { build } from "esbuild";
import valibotToJsonSchema from "unplugin-valibot-to-json-schema/esbuild";

build({
  plugins: [valibotToJsonSchema()],
});

Rspack

// rspack.config.js
import valibotToJsonSchema from "unplugin-valibot-to-json-schema/rspack";

export default {
  plugins: [
    valibotToJsonSchema({
      // options
    }),
  ],
};

Example

Before transformation:

import { toJsonSchema } from "@valibot/to-json-schema";
import * as v from "valibot";

const minUserId = 1;

const userSearchSchema = v.object({
  userId: v.pipe(
    v.number(),
    v.integer(),
    v.minValue(minUserId),
    v.description("User identifier"),
  ),
  startDate: v.pipe(
    v.string(),
    v.isoDate("Expected an ISO date"),
    v.description("Search start date"),
  ),
});

export const searchUsersDefinition = {
  name: "search_users",
  schema: toJsonSchema(userSearchSchema),
};

After transformation (build output):

import * as v from "valibot";

const minUserId = 1;

const userSearchSchema = v.object({
  userId: v.pipe(
    v.number(),
    v.integer(),
    v.minValue(minUserId),
    v.description("User identifier"),
  ),
  startDate: v.pipe(
    v.string(),
    v.isoDate("Expected an ISO date"),
    v.description("Search start date"),
  ),
});

export const searchUsersDefinition = {
  name: "search_users",
  schema: {
    $schema: "http://json-schema.org/draft-07/schema#",
    type: "object",
    properties: {
      userId: {
        type: "integer",
        minimum: 1,
        description: "User identifier",
      },
      startDate: {
        type: "string",
        format: "date",
        description: "Search start date",
      },
    },
    required: ["userId", "startDate"],
    additionalProperties: true,
  },
};

The toJsonSchema call is gone, the JSON Schema is inline, and @valibot/to-json-schema is no longer imported.

Options

interface PluginOptions {
  // Only transform files whose id matches this RegExp
  include?: RegExp;
  // Skip files whose id matches this RegExp
  exclude?: RegExp;
}

Limitations

  • Schemas that cannot be statically evaluated (e.g. dependency on runtime-only values that are not resolvable at build time) may fail — check the error message and report them here :]

Credits