nuxt-safe-runtime-config
Nuxt Safe Runtime Config
Validate Nuxt runtime config at build time using Zod, Valibot, ArkType, or any Standard Schema compatible library.
๐ Related Nuxt RFC: Enable Standard Schema Validation in Nuxt Config
Features
- ๐ Build-time validation with Zod, Valibot, ArkType, or any Standard Schema library
- ๐ Runtime validation (opt-in) validates config when the server starts
- โจ Auto-generated types โ
useSafeRuntimeConfig()is fully typed without manual generics - ๐ ESLint plugin warns when using
useRuntimeConfig()instead of the type-safe composable - โก Zero runtime overhead by default โ validation happens at build time only
Quick Setup
Install the module:
npx nuxi module add nuxt-safe-runtime-config
Usage
1. Define your schema
Use Zod, Valibot, ArkType, or any Standard Schema compatible library:
With Valibot
import { number, object, optional, string } from 'valibot'
const runtimeConfigSchema = object({
public: object({
apiBase: string(),
appName: optional(string()),
}),
databaseUrl: string(),
secretKey: string(),
port: optional(number()),
})
With Zod
import { z } from 'zod'
const runtimeConfigSchema = z.object({
public: z.object({
apiBase: z.string(),
appName: z.string().optional(),
}),
databaseUrl: z.string(),
secretKey: z.string(),
port: z.number().optional(),
})
With ArkType
import { type } from 'arktype'
const runtimeConfigSchema = type({
'public': {
'apiBase': 'string',
'appName?': 'string'
},
'databaseUrl': 'string',
'secretKey': 'string',
'port?': 'number'
})
2. Configure in nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-safe-runtime-config'],
runtimeConfig: {
databaseUrl: process.env.DATABASE_URL || 'postgresql://localhost:5432/mydb',
secretKey: process.env.SECRET_KEY || 'default-secret-key',
port: Number.parseInt(process.env.PORT || '3000'),
public: {
apiBase: process.env.PUBLIC_API_BASE || 'https://api.example.com',
appName: 'My Nuxt App',
},
},
safeRuntimeConfig: {
$schema: runtimeConfigSchema,
},
})
3. Use the type-safe composable
Access your validated config with full type safety โ types are auto-generated from your schema:
<script setup lang="ts">
const config = useSafeRuntimeConfig()
// config.public.apiBase is typed as string
// config.secretKey is typed as string
</script>
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
$schema | StandardSchemaV1 | โ | Your validation schema (required) |
validateAtBuild | boolean | true | Validate during dev/build |
validateAtRuntime | boolean | false | Validate when server starts |
onBuildError | 'throw' | 'warn' | 'ignore' | 'throw' | How to handle build validation errors |
onRuntimeError | 'throw' | 'warn' | 'ignore' | 'throw' | How to handle runtime validation errors |
logSuccess | boolean | true | Log successful validation |
logFallback | boolean | true | Log when using JSON Schema fallback |
jsonSchemaTarget | string | 'draft-2020-12' | JSON Schema version for runtime validation |
Runtime Validation
By default, validation only runs at build time. Enable runtime validation to catch environment variable issues when the server starts:
export default defineNuxtConfig({
safeRuntimeConfig: {
$schema: runtimeConfigSchema,
validateAtRuntime: true,
},
})
Runtime validation uses @cfworker/json-schema to validate the config after environment variables are merged. This lightweight validator (~8KB) works on all runtimes including edge (Cloudflare Workers, Vercel Edge, Netlify Edge). It catches issues like:
- Environment variables with wrong types (e.g.,
NUXT_PORT=abcwhen expecting a number) - Missing required environment variables in production
- Invalid values that pass build-time checks but fail at runtime
ESLint Integration
The module includes an ESLint plugin that warns when using useRuntimeConfig() instead of useSafeRuntimeConfig().
With @nuxt/eslint (Automatic)
If you use @nuxt/eslint, the rule is auto-registered. No configuration needed.
Manual Setup
Add to your eslint.config.mjs:
import safeRuntimeConfig from 'nuxt-safe-runtime-config/eslint'
export default [
safeRuntimeConfig.configs.recommended,
// ... your other configs
]
Or configure manually:
import safeRuntimeConfig from 'nuxt-safe-runtime-config/eslint'
export default [
{
plugins: { 'safe-runtime-config': safeRuntimeConfig },
rules: { 'safe-runtime-config/prefer-safe-runtime-config': 'warn' },
},
]
The rule includes auto-fix support โ run eslint --fix to automatically replace useRuntimeConfig() calls.
Type Safety
Types are auto-generated at build time from your schema's JSON Schema representation. The useSafeRuntimeConfig() composable returns a fully typed object โ no manual generics needed:
const config = useSafeRuntimeConfig()
// config is fully typed based on your schema
Generated types are stored in .nuxt/types/safe-runtime-config.d.ts and automatically included in your project.
Error Messages
When validation fails, you see detailed error messages:
[safe-runtime-config] Validation failed!
1. databaseUrl: Invalid type: Expected string but received undefined
2. public.apiBase: Invalid type: Expected string but received undefined
3. port: Invalid type: Expected number but received string
The module stops the build process until all validation errors are resolved.
Why This Module?
Nuxt's built-in schema validation is designed for module authors and broader configuration. This module focuses specifically on runtime config validation using Standard Schema, allowing you to:
- Use your preferred validation library (Valibot, Zod, ArkType)
- Catch configuration errors at build time
- Optionally validate at runtime for environment variable issues
- Get full type safety in your components
Contribution
Local development
# Install dependencies
pnpm install
# Generate type stubs
pnpm run dev:prepare
# Develop with the playground
pnpm run dev
# Build the playground
pnpm run dev:build
# Run ESLint
pnpm run lint
# Run Vitest
pnpm run test
pnpm run test:watch
# Release new version
pnpm run release