Smart Coercion Plugin
Automatically converts values to match your schema types without requiring manual coercion logic.
WARNING
This plugin improves developer experience, but it adds runtime overhead. For performance sensitive applications or complex schemas, manual coercion in your validation layer is usually more efficient.
Installation
npm install @orpc/json-schema@betayarn add @orpc/json-schema@betapnpm add @orpc/json-schema@betabun add @orpc/json-schema@betadeno add npm:@orpc/json-schema@betaSetup
Use SmartCoercionHandlerPlugin in your handler to coerce incoming request data to the expected .input schema:
import { SmartCoercionHandlerPlugin } from '@orpc/json-schema'
const handler = new OpenAPIHandler(router, {
plugins: [
new SmartCoercionHandlerPlugin({
converters: [
new ZodToJsonSchemaConverter(),
// Add other schema converters as needed
],
})
]
})Use SmartCoercionLinkPlugin in your link to coerce server responses to the expected .output or .errors schemas:
import { SmartCoercionLinkPlugin } from '@orpc/json-schema'
const link = new OpenAPILink(contract, {
plugins: [
new SmartCoercionLinkPlugin(contract, {
converters: [
new ZodToJsonSchemaConverter(),
// Add other schema converters as needed
],
}),
]
})INFO
This plugin relies on JSON Schema Converters to determine how values should be coerced. Configure the appropriate converter for each validation library you use. If a required converter is unavailable, it automatically falls back to Standard Json Schema conversion.
How It Works
The plugin coerces values safely by following these rules:
- Schema-driven: Converts only when the schema defines the target type
- Safe only: Converts only values with an unambiguous representation, such as
'123'to123 - Preserve original values: Leaves the original value unchanged when conversion would be unsafe
- Union-aware: Picks the best match for union types
- Deep conversion: Applies recursively inside nested objects and arrays
INFO
JSON Schema does not natively represent BigInt, Date, RegExp, URL, Set, or Map. For these types, oRPC relies on x-native-type metadata in your schema:
x-native-type: 'bigint'for BigIntx-native-type: 'date'for Datex-native-type: 'regexp'for RegExpx-native-type: 'url'for URLx-native-type: 'set'for Setx-native-type: 'map'for Map
The built-in Standard Json Schema converter handles these cases. Because this metadata is outside the official JSON Schema specification, custom converters may need to add the appropriate x-native-type values explicitly.
Conversion Rules
String → Boolean
Supports these specific string values, case-insensitively:
'true','on'→true'false','off'→false
INFO
HTML <input type="checkbox"> elements commonly submit 'on' or 'off', so this conversion is especially useful for form handling.
String → Number
Supports valid numeric strings:
'123'→123'3.14'→3.14
String/Number → BigInt
Supports valid numeric strings or numbers:
'12345678901234567890'→12345678901234567890n12345678901234567890→12345678901234567890n
String → Date
Supports ISO date and datetime strings:
'2023-10-01'→new Date('2023-10-01')'2020-01-01T06:15'→new Date('2020-01-01T06:15')'2020-01-01T06:15Z'→new Date('2020-01-01T06:15Z')'2020-01-01T06:15:00Z'→new Date('2020-01-01T06:15:00Z')'2020-01-01T06:15:00.123Z'→new Date('2020-01-01T06:15:00.123Z')
String → RegExp
Supports valid regular expression strings:
'/^\\d+$/i'→new RegExp('^\\d+$', 'i')'/abc/'→new RegExp('abc')
String → URL
Supports valid URL strings:
'https://example.com'→new URL('https://example.com')
Array → Set
Supports arrays of unique values:
['apple', 'banana']→new Set(['apple', 'banana'])
Array → Object
Converts arrays into objects with numeric keys:
['apple', 'banana']→{ 0: 'apple', 1: 'banana' }
INFO
This is particularly useful for Bracket Notation when you need objects with numeric keys.
Array → Map
Supports arrays of key-value pairs with unique keys:
[['key1', 'value1'], ['key2', 'value2']]→new Map([['key1', 'value1'], ['key2', 'value2']])
Advanced Usage
You can also use this plugin in guides such as Expanding Type Support for OpenAPI Link.
Learn More
For implementation details, see the SmartCoercionHandlerPlugin source code or the SmartCoercionLinkPlugin source code.

