Skip to content

Releases: unnoq/orpc

v1.2.0

05 May 14:52
Compare
Choose a tag to compare

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

   🐞 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

26 Apr 13:05
Compare
Choose a tag to compare

   🐞 Bug Fixes

    View changes on GitHub

v1.1.0

22 Apr 14:30
Compare
Choose a tag to compare

✨ [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

  • deps: Update dependency rou3 to ^0.6.0  -  in #423 (16739)
    View changes on GitHub

v1.0.3

15 Apr 14:27
Compare
Choose a tag to compare

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

12 Apr 13:49
Compare
Choose a tag to compare
v1.0.0-beta.7 Pre-release
Pre-release

🚀 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

12 Apr 13:48
Compare
Choose a tag to compare

   🚨 Breaking Changes

   🚀 Features

  • client: Pass isSuccess to ClientRetryPlugin onRetry returned callback  -  by @unnoq in #389 (b3c3a)
  • server: Error on unsupported batch response types  -  by @unnoq in #355 (bb258)

   🐞 Bug Fixes

   🏎 Performance

    View changes on GitHub

v1.0.0-beta.6

09 Apr 14:10
Compare
Choose a tag to compare
v1.0.0-beta.6 Pre-release
Pre-release

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 to isSuccess in the safe utility for clarity.
  • Updated the onFinish callback state to align with the safe 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 for RPCHandler) 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

09 Apr 14:09
Compare
Choose a tag to compare

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 to isSuccess in the safe utility for clarity.
  • Updated the onFinish callback state to align with the safe 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 for RPCHandler) 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

   🐞 Bug Fixes

   🏎 Performance

  • standard-server: Optimize event-iterator payload for void returns  -  by @unnoq (f4735)
    View changes on GitHub

v1.0.0-beta.5

31 Mar 14:33
Compare
Choose a tag to compare
v1.0.0-beta.5 Pre-release
Pre-release

🚨 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

31 Mar 14:33
Compare
Choose a tag to compare

🚨 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

   🚀 Features

   🐞 Bug Fixes

    View changes on GitHub