Skip to content
oRPC
Esc
navigateopen⌘Jpreview
On this page

Expanding Type Support for OpenAPI Link

Because of OpenAPI Serializer limitations, values like Date and bigint are received by the client in JSON-friendly form. You can convert them back to native types on the client with either Response Validation Plugin or Smart Coercion Plugin, but only under the conditions described below.

Choose a Plugin

  • Use Response Validation Plugin when you want manual control over coercion logic and can define explicit coercion rules in your schemas.
  • Use Smart Coercion Plugin when you want automatic coercion based on schema instead of defining coercion logic yourself.

Use Response Validation Plugin

Use Response Validation Plugin when you want to manually control how values are converted back to native types. The coercion rules live in your contract schemas, so the behavior stays explicit and predictable.

const contract = oc.output(z.object({
  date: z.coerce.date<Date>(),
  bigint: z.coerce.bigint<bigint>(),
}))

const procedure = implement(contract).handler(() => ({
  date: new Date(),
  bigint: 123n,
}))

The server still returns JSON-friendly data:

const rawOutput = {
  date: '2025-09-01T07:24:39.000Z',
  bigint: '123',
}

With ResponseValidationLinkPlugin, the client validates that response and applies your schema coercion before your code uses it.

const output = {
  date: new Date('2025-09-01T07:24:39.000Z'),
  bigint: 123n,
}

Setup

Add the plugin to your link, then remove the JsonifiedClient wrapper from the client type.

import type { RouterContractClient } from '@orpc/contract'
import { ResponseValidationLinkPlugin } from '@orpc/contract/plugins'

const link = new OpenAPILink(contract, {
  plugins: [
    new ResponseValidationLinkPlugin(contract), 
  ],
})

const client: JsonifiedClient<RouterContractClient<typeof contract>> = createORPCClient(link) 
const client: RouterContractClient<typeof contract> = createORPCClient(link) 

Use Smart Coercion Plugin

Use Smart Coercion Plugin when you want the client to coerce values automatically from schema instead of adding coercion logic to each schema manually.

import type { RouterContractClient } from '@orpc/contract'
import { SmartCoercionLinkPlugin } from '@orpc/json-schema'

const link = new OpenAPILink(contract, {
  plugins: [
    new SmartCoercionLinkPlugin(contract), 
  ],
})

const client: JsonifiedClient<RouterContractClient<typeof contract>> = createORPCClient(link) 
const client: RouterContractClient<typeof contract> = createORPCClient(link) 

Last updated on August 6, 2026

Was this page helpful?