Valibot

Valibot is a modular validation library with excellent tree-shaking. Only the functions you use are bundled.

Installation

npm install valibot

Basic Schema

nuxt.config.ts
import { number, object, optional, string } from 'valibot'

const runtimeConfigSchema = object({
  public: object({
    apiBase: string(),
    appName: optional(string()),
  }),
  databaseUrl: string(),
  secretKey: string(),
  port: optional(number()),
})

export default defineNuxtConfig({
  modules: ['nuxt-safe-runtime-config'],

  runtimeConfig: {
    databaseUrl: process.env.DATABASE_URL || '',
    secretKey: process.env.SECRET_KEY || '',
    port: Number.parseInt(process.env.PORT || '3000'),
    public: {
      apiBase: process.env.NUXT_PUBLIC_API_BASE || 'https://api.example.com',
      appName: 'My App',
    },
  },

  safeRuntimeConfig: {
    $schema: runtimeConfigSchema,
  },
})

Common Patterns

Required vs Optional

import { object, string, optional, number } from 'valibot'

object({
  required: string(),           // must exist, must be string
  optional: optional(string()), // can be undefined
  withDefault: optional(number(), 3000), // default if undefined
})

String Validations

import { string, email, url, minLength, maxLength, regex, pipe } from 'valibot'

object({
  email: pipe(string(), email()),
  apiUrl: pipe(string(), url()),
  token: pipe(string(), minLength(32)),
  slug: pipe(string(), regex(/^[a-z-]+$/)),
})

Number Validations

import { number, integer, minValue, maxValue, pipe } from 'valibot'

object({
  port: pipe(number(), integer(), minValue(1), maxValue(65535)),
  timeout: pipe(number(), minValue(0)),
})

Enums

import { picklist } from 'valibot'

object({
  environment: picklist(['development', 'staging', 'production']),
  logLevel: picklist(['debug', 'info', 'warn', 'error']),
})

Nested Objects

import { object, string, array } from 'valibot'

object({
  public: object({
    api: object({
      baseUrl: string(),
      version: string(),
    }),
  }),
  redis: object({
    host: string(),
    port: number(),
  }),
})

Full Example

nuxt.config.ts
import { email, number, object, optional, picklist, pipe, string, url } from 'valibot'

const runtimeConfigSchema = object({
  public: object({
    apiBase: pipe(string(), url()),
    appName: string(),
    environment: picklist(['development', 'staging', 'production']),
  }),
  database: object({
    url: string(),
    poolSize: optional(number()),
  }),
  auth: object({
    jwtSecret: string(),
    sessionTtl: number(),
  }),
  email: optional(object({
    host: string(),
    port: number(),
    from: pipe(string(), email()),
  })),
})

export default defineNuxtConfig({
  modules: ['nuxt-safe-runtime-config'],
  safeRuntimeConfig: { $schema: runtimeConfigSchema },
})