Releases: unnoq/orpc
v1.2.0
Websocket Support
We have adapters for Bun, Node, Deno, Crossws, ... docs here
import { experimental_RPCHandler as RPCHandler } from '@orpc/server/bun-ws'
const handler = new RPCHandler(router)
Bun.serve({
fetch(req, server) {
if (server.upgrade(req)) {
return
}
return new Response('Upgrade failed', { status: 500 })
},
websocket: {
message(ws, message) {
handler.message(ws, message, {
context: {}, // Provide initial context if needed
})
},
close(ws) {
handler.close(ws)
},
},
})
Zod 4 support
import {
experimental_ZodSmartCoercionPlugin as ZodSmartCoercionPlugin
} from '@orpc/zod/zod4' // <-- zod v4
import {
experimental_ZodToJsonSchemaConverter as ZodToJsonSchemaConverter
} from '@orpc/zod/zod4' // <-- zod v4
🚀 Features
- Support
HEAD
method - by @unnoq in #468 (075ee) - openapi: CreateJsonifiedRouterClient - by @unnoq in #449 (a2fc0)
- react: Use useTransition within useServerAction - by @unnoq in #459 (95b67)
- standard-server: Server adapter for connected peers - by @unnoq in #456 (98784)
- zod: Experimental support zod v4 - by @unnoq in #462 (d5f6b)
🐞 Bug Fixes
- openapi: Inline spec into scalar html (OpenAPI Reference Plugin) - by @unnoq in #469 (77566)
- server: SSE with keepalive crashes server on client disconnect - by @unnoq in #464 (13307)
- standard-server: Improve event-iterator cleanup - by @unnoq in #466 (24429)
View changes on GitHub
v1.1.1
🐞 Bug Fixes
View changes on GitHub
v1.1.0
✨ [NEW] OpenAPI Reference Plugin (Swagger/Scalar)
Easy serve beautiful OpenAPI Reference Client UI powered by Scalar
const handler = new OpenAPIHandler(router, {
plugins: [
new OpenAPIReferencePlugin({
schemaConverters: [
new ZodToJsonSchemaConverter(),
],
specGenerateOptions: {
info: {
title: 'ORPC Playground',
version: '1.0.0',
},
},
}),
]
})
✨ [NEW] Partical React Native Support
React Native includes a Fetch API, so you can use oRPC out of the box. However, the Fetch API in React Native has limitations. oRPC features like File, Blob, and AsyncIteratorObject aren't supported. Follow Support Stream #27741 for updates.
🚀 Features
- client: Batch Plugin auto‑infer context from link - by @unnoq in #427 (ff41b)
- openapi: OpenAPI Reference Plugin - by @unnoq in #442 (7336c)
- server: Allow .concat middlewares with narrowed input types - by @unnoq in #420 (2d41a)
- standard-server: Support React Native by explicitly checking body - by @unnoq in #445 (41631)
🐞 Bug Fixes
View changes on GitHub
v1.0.3
Finally oRPC v1 here ❤️🔥❤️🔥
Read announcement and oRPC story here: https://orpc.unnoq.com/blog/v1-announcement
oRPC vs X
- oRPC is 1,6 times typecheck faster (5.9s vs 9.3s)
- oRPC is 2,8 times runtime faster (295k reqs vs 104k reqs / 20 sec)
- oRPC is 1,26 times less max cpu usage (102% vs 129%)
- oRPC is 2,6 times less max ram usage (103MB vs 268MB)
- oRPC is 2 times smaller in bundle size (32.3 kB vs 65.5 kB)
🚀 Features
View changes on GitHub
v1.0.0-beta.7
🚀 Improve and bug fixed for BatchPlugin and RetryPlugin
🚨 Remove built-in hono.dev and nextjs.org integrations (check the docs to create your own)
No significant changes
View changes on GitHub
v0.54.0
v1.0.0-beta.6
✨ Batch Reqeusts/Responses
The Batch Request/Response Plugin allows you to combine multiple requests and responses into a single batch, reducing the overhead of sending each one separately. Read more
🚨 Breaking Changes 🚨
- Renamed
success
toisSuccess
in thesafe
utility for clarity. - Updated the
onFinish
callback state to align with thesafe
utility's output. - Revised configuration options for
RPCLink
,OpenAPILink
, interceptors, and plugins. - Included the full response data in
MalformedResponseError
to simplify debugging.
✨ Features ✨
- Added dynamic retry logic support to the
ClientRetry
plugin. - Introduced
StrictGetMethodPlugin
(enabled by default forRPCHandler
) to enforce GET usage. - Added a simple CSRF protection plugin.
- Added a request/response batching plugin.
- Links (
RPCLink
,OpenAPILink
) now support search queries directly in the base URL. - Made plugin execution order configurable.
🐞 Bug Fixes 🐞
- Fixed OpenAPI spec generation for optional response bodies.
- Fixed file deserialization errors involving empty filenames.
- Resolved issues using
onSuccess
/onError
hooks as middleware. - Improved type inference in certain scenarios.
- Fixed issues resulting from repeated
.next
calls. - Corrected server-side URL prefix handling.
🏎 Performance 🏎
- Optimized the payload size for void returns in
event-iterator
.
No significant changes
View changes on GitHub
v0.53.0
✨ Batch Reqeusts/Responses
The Batch Request/Response Plugin allows you to combine multiple requests and responses into a single batch, reducing the overhead of sending each one separately. Read more
🚨 Breaking Changes 🚨
- Renamed
success
toisSuccess
in thesafe
utility for clarity. - Updated the
onFinish
callback state to align with thesafe
utility's output. - Revised configuration options for
RPCLink
,OpenAPILink
, interceptors, and plugins. - Included the full response data in
MalformedResponseError
to simplify debugging.
✨ Features ✨
- Added dynamic retry logic support to the
ClientRetry
plugin. - Introduced
StrictGetMethodPlugin
(enabled by default forRPCHandler
) to enforce GET usage. - Added a simple CSRF protection plugin.
- Added a request/response batching plugin.
- Links (
RPCLink
,OpenAPILink
) now support search queries directly in the base URL. - Made plugin execution order configurable.
🐞 Bug Fixes 🐞
- Fixed OpenAPI spec generation for optional response bodies.
- Fixed file deserialization errors involving empty filenames.
- Resolved issues using
onSuccess
/onError
hooks as middleware. - Improved type inference in certain scenarios.
- Fixed issues resulting from repeated
.next
calls. - Corrected server-side URL prefix handling.
🏎 Performance 🏎
- Optimized the payload size for void returns in
event-iterator
.
🚨 Breaking Changes
🚀 Features
- client:
- client, server:
- server:
🐞 Bug Fixes
.next
broken when calling multiple times - by @unnoq in #337 (25532)- openapi:
- server:
- standard-server:
🏎 Performance
View changes on GitHub
v1.0.0-beta.5
🚨 Breaking Change Server Action
🚨
The Server Action has been completely remake and you need upgrade your code to reflect new changes
Tuple return
'use client'
// before
const data = await ping({ name })
// now
const [error, data] = await ping({ name })
Support Typesafe error handling
'use client'
const [error, data] = await someAction({ name: 'John' })
if (error) {
if (error.defined) {
console.log(error.data)
// ^ Typed error data
}
// Handle unknown errors
}
else {
// Handle success
console.log(data)
}
useServerAction
Hook
The useServerAction
hook simplifies invoking server actions in React.
const { execute, data, error, status } = useServerAction(someAction, {
interceptors: [
onError((error) => {
if (isDefinedError(error)) {
console.error(error.data)
// ^ Typed error data
}
}),
],
})
createFormAction
Utility
The createFormAction
utility accepts a procedure and returns a function to handle form submissions. It uses Bracket Notation to deserialize form data.
import { createFormAction } from '@orpc/react'
const dosomething = os
.input(
z.object({
user: z.object({
name: z.string(),
age: z.coerce.number(),
}),
})
)
.handler(({ input }) => {
console.log('Form action called!')
console.log(input)
})
export const redirectSomeWhereForm = createFormAction(dosomething, {
interceptors: [
onSuccess(async () => {
redirect('/some-where')
}),
],
})
export function MyComponent() {
return (
<form action={redirectSomeWhereForm}>
<input type="text" name="user[name]" required />
<input type="number" name="user[age]" required />
<button type="submit">Submit</button>
</form>
)
}
🚀 Features
OpenAPILink
OpenAPILink enables communication with an OpenAPIHandler on your server using HTTP/Fetch.
const link = new OpenAPILink(contract, {
url: 'http://localhost:3000/api',
headers: () => ({
'x-api-key': 'my-api-key',
}),
// fetch: <-- polyfill fetch if needed
})
Support 3xx response
By combining the successStatus
and outputStructure
options, you can return a standard HTTP redirect response.
const redirect = os
.route({
method: 'GET',
path: '/redirect',
successStatus: 307,
outputStructure: 'detailed'
})
.handler(async () => {
return {
headers: {
location: 'https://orpc.unnoq.com',
},
}
})
And many other improvements
No significant changes
View changes on GitHub
v0.52.0
🚨 Breaking Change Server Action
🚨
The Server Action has been completely remake and you need upgrade your code to reflect new changes
Tuple return
'use client'
// before
const data = await ping({ name })
// now
const [error, data] = await ping({ name })
Support Typesafe error handling
'use client'
const [error, data] = await someAction({ name: 'John' })
if (error) {
if (error.defined) {
console.log(error.data)
// ^ Typed error data
}
// Handle unknown errors
}
else {
// Handle success
console.log(data)
}
useServerAction
Hook
The useServerAction
hook simplifies invoking server actions in React.
const { execute, data, error, status } = useServerAction(someAction, {
interceptors: [
onError((error) => {
if (isDefinedError(error)) {
console.error(error.data)
// ^ Typed error data
}
}),
],
})
createFormAction
Utility
The createFormAction
utility accepts a procedure and returns a function to handle form submissions. It uses Bracket Notation to deserialize form data.
import { createFormAction } from '@orpc/react'
const dosomething = os
.input(
z.object({
user: z.object({
name: z.string(),
age: z.coerce.number(),
}),
})
)
.handler(({ input }) => {
console.log('Form action called!')
console.log(input)
})
export const redirectSomeWhereForm = createFormAction(dosomething, {
interceptors: [
onSuccess(async () => {
redirect('/some-where')
}),
],
})
export function MyComponent() {
return (
<form action={redirectSomeWhereForm}>
<input type="text" name="user[name]" required />
<input type="number" name="user[age]" required />
<button type="submit">Submit</button>
</form>
)
}
🚀 Features
OpenAPILink
OpenAPILink enables communication with an OpenAPIHandler on your server using HTTP/Fetch.
const link = new OpenAPILink(contract, {
url: 'http://localhost:3000/api',
headers: () => ({
'x-api-key': 'my-api-key',
}),
// fetch: <-- polyfill fetch if needed
})
Support 3xx response
By combining the successStatus
and outputStructure
options, you can return a standard HTTP redirect response.
const redirect = os
.route({
method: 'GET',
path: '/redirect',
successStatus: 307,
outputStructure: 'detailed'
})
.handler(async () => {
return {
headers: {
location: 'https://orpc.unnoq.com',
},
}
})
And many other improvements
🚨 Breaking Changes
- client:
- server:
- server, react:
- standard-server:
🚀 Features
- client, contract, openapi: Support 3xx response - by @unnoq in #304 (30c0e)
- client, server: Allow numbers and symbols as context keys - by @unnoq in #312 (10ace)
- openapi: OpenAPILink - by @unnoq in #303 (a2467)
- server: Support config
ThrowableError
- by @unnoq in #311 (d1f8e)