Skip to content

Commit d438821

Browse files
authored
feat(swr): SWR integration (#1723)
## Summary Adds `@orpc/swr`, the [SWR](https://swr.vercel.app/) integration for oRPC v2 (successor of v1's `@orpc/experimental-react-swr`, now marked stable), plus a [documentation page](https://orpc.dev/docs/integrations/swr). ```ts import { createSWRUtils } from '@orpc/swr' const orpc = createSWRUtils(client) const { data } = useSWR( orpc.planet.find.key({ input: { id: 123 } }), orpc.planet.find.fetcher(), ) const mutation = useSWRMutation( orpc.planet.list.key(), orpc.planet.create.mutator(), ) mutate(orpc.planet.matcher()) // invalidate all planet data ``` ## What you get - `.key`, `.fetcher`, `.mutator`, `.subscriber`, `.liveSubscriber`, `.call`, and `.matcher` for `useSWR`, `useSWRInfinite`, `useSWRMutation`, and `useSWRSubscription` - Key utils follow the `@orpc/tanstack-query` conventions: `generateOperationKey`, `OperationKey`, and a `prefix` option to avoid key conflicts when multiple router utils share the same client - Operation context (with `key` and `type`) is added to the client context on every call, so links can adjust behavior per operation - `.subscriber` and `.liveSubscriber` consume an [AsyncIteratorObject](https://orpc.dev/docs/async-iterator-object) output, with `refetchMode` and `maxChunks` options for chunked subscriptions - 100% test coverage - `@orpc/swr` added to the package list across README files
1 parent cfe1839 commit d438821

51 files changed

Lines changed: 2128 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ You can read the documentation [here](https://orpc.dev).
5252
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
5353
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
5454
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
55+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
5556
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
5657
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
5758
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).

apps/content/.vitepress/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ export default withMermaid(defineConfig({
196196
{ text: 'OpenTelemetry', link: '/docs/integrations/opentelemetry' },
197197
{ text: 'Pinia Colada', link: '/docs/integrations/pinia-colada' },
198198
{ text: 'Pino', link: '/docs/integrations/pino' },
199+
{ text: 'SWR', link: '/docs/integrations/swr' },
199200
{ text: 'Standard Schema', link: '/docs/integrations/standard-schema' },
200201
{ text: 'Tanstack Query', link: '/docs/integrations/tanstack-query' },
201202
{ text: 'tRPC', link: '/docs/integrations/trpc' },
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# SWR Integration
2+
3+
[SWR](https://swr.vercel.app/) is a React Hooks library for data fetching that provides features like caching, revalidation, and more. oRPC SWR integration is very lightweight and straightforward. There is no extra overhead.
4+
5+
::: warning
6+
This guide assumes you are already familiar with [SWR](https://swr.vercel.app/). If you need a refresher, review the official SWR documentation before continuing.
7+
:::
8+
9+
## Installation
10+
11+
::: code-group
12+
13+
```sh [npm]
14+
npm install @orpc/swr@beta
15+
```
16+
17+
```sh [yarn]
18+
yarn add @orpc/swr@beta
19+
```
20+
21+
```sh [pnpm]
22+
pnpm add @orpc/swr@beta
23+
```
24+
25+
```sh [bun]
26+
bun add @orpc/swr@beta
27+
```
28+
29+
```sh [deno]
30+
deno add npm:@orpc/swr@beta
31+
```
32+
33+
:::
34+
35+
## Setup
36+
37+
Before you begin, set up either a [server-side client](/docs/client/server-side) or a [client-side client](/docs/client/client-side).
38+
39+
```ts
40+
import { createSWRUtils } from '@orpc/swr'
41+
42+
export const orpc = createSWRUtils(client)
43+
44+
orpc.planet.find.key({ input: { id: 123 } })
45+
```
46+
47+
::: details Avoiding Key Conflicts?
48+
49+
You can avoid key conflicts by passing a unique prefix when creating your utils:
50+
51+
```ts
52+
const userORPC = createSWRUtils(userClient, {
53+
prefix: 'user'
54+
})
55+
56+
const postORPC = createSWRUtils(postClient, {
57+
prefix: 'post'
58+
})
59+
```
60+
61+
:::
62+
63+
## Data Fetching
64+
65+
Use `.key` and `.fetcher` methods to configure `useSWR` for data fetching:
66+
67+
```ts
68+
import useSWR from 'swr'
69+
70+
const { data, error, isLoading } = useSWR(
71+
orpc.planet.find.key({ input: { id: 123 } }),
72+
orpc.planet.find.fetcher({ context: { cache: true } }), // Provide client context if needed
73+
)
74+
```
75+
76+
## Infinite Queries
77+
78+
Use `.key` and `.fetcher` methods to configure `useSWRInfinite` for infinite queries:
79+
80+
```ts
81+
import useSWRInfinite from 'swr/infinite'
82+
83+
const { data, error, isLoading, size, setSize } = useSWRInfinite(
84+
(index, previousPageData) => {
85+
if (previousPageData && !previousPageData.nextCursor) {
86+
return null // reached the end
87+
}
88+
89+
return orpc.planet.list.key({ input: { cursor: previousPageData?.nextCursor } })
90+
},
91+
orpc.planet.list.fetcher({ context: { cache: true } }), // Provide client context if needed
92+
)
93+
```
94+
95+
## Subscriptions
96+
97+
Use `.key` and `.subscriber` methods to configure `useSWRSubscription` to subscribe to an [AsyncIteratorObject](/docs/async-iterator-object):
98+
99+
```ts
100+
import useSWRSubscription from 'swr/subscription'
101+
102+
const { data, error } = useSWRSubscription(
103+
orpc.streamed.key({ input: { id: 3 } }),
104+
orpc.streamed.subscriber({ context: { cache: true }, maxChunks: 10 }), // Provide client context if needed
105+
)
106+
```
107+
108+
Use `.liveSubscriber` to subscribe to the latest events without chunking:
109+
110+
```ts
111+
import useSWRSubscription from 'swr/subscription'
112+
113+
const { data, error } = useSWRSubscription(
114+
orpc.streamed.key({ input: { id: 3 } }),
115+
orpc.streamed.liveSubscriber({ context: { cache: true } }), // Provide client context if needed
116+
)
117+
```
118+
119+
## Mutations
120+
121+
Use `.key` and `.mutator` methods to configure `useSWRMutation` for mutations with automatic revalidation on success:
122+
123+
```ts
124+
import useSWRMutation from 'swr/mutation'
125+
126+
const { trigger, isMutating } = useSWRMutation(
127+
orpc.planet.list.key(),
128+
orpc.planet.create.mutator({ context: { cache: true } }), // Provide client context if needed
129+
)
130+
131+
trigger({ name: 'New Planet' }) // auto revalidate orpc.planet.list.key() on success
132+
```
133+
134+
## Manual Revalidation
135+
136+
Use `.matcher` to invalidate data manually:
137+
138+
```ts
139+
import { mutate } from 'swr'
140+
141+
mutate(orpc.matcher()) // invalidate all orpc data
142+
mutate(orpc.planet.matcher()) // invalidate all planet data
143+
mutate(orpc.planet.find.matcher({ input: { id: 123 }, strategy: 'exact' })) // invalidate specific planet data
144+
```
145+
146+
## Calling Clients
147+
148+
Use `.call` to call a procedure client directly. It's an alias for corresponding procedure client.
149+
150+
```ts
151+
const planet = await orpc.planet.find.call({ id: 123 })
152+
```
153+
154+
## Operation Context
155+
156+
When clients are invoked through the SWR integration, an **operation context** is automatically added to the [client context](/docs/client/rpc-link#using-client-context). This context can be used to configure the request behavior, like setting the HTTP method.
157+
158+
```ts
159+
import {
160+
SWR_OPERATION_CONTEXT_SYMBOL,
161+
SWROperationContext,
162+
} from '@orpc/swr'
163+
164+
interface ClientContext extends SWROperationContext {
165+
}
166+
167+
const GET_OPERATION_TYPE = new Set(['fetcher', 'subscriber', 'liveSubscriber'])
168+
169+
const link = new RPCLink<ClientContext>({
170+
method: ({ context }, path) => {
171+
const operationType = context[SWR_OPERATION_CONTEXT_SYMBOL]?.type
172+
173+
if (operationType && GET_OPERATION_TYPE.has(operationType)) {
174+
return 'GET'
175+
}
176+
177+
return 'POST'
178+
},
179+
})
180+
```

packages/ai-sdk/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ You can read the documentation [here](https://orpc.dev).
5252
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
5353
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
5454
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
55+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
5556
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
5657
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
5758
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).

packages/arktype/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ You can read the documentation [here](https://orpc.dev).
5252
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
5353
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
5454
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
55+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
5556
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
5657
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
5758
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).

packages/bun/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ You can read the documentation [here](https://orpc.dev).
4949
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
5050
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
5151
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
52+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
5253
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
5354
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
5455
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).

packages/client/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ You can read the documentation [here](https://orpc.dev).
5252
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
5353
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
5454
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
55+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
5556
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
5657
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
5758
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).

packages/cloudflare/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ You can read the documentation [here](https://orpc.dev).
5252
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
5353
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
5454
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
55+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
5556
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
5657
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
5758
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).

packages/contract/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ You can read the documentation [here](https://orpc.dev).
5252
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
5353
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
5454
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
55+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
5556
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
5657
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
5758
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).

packages/effect/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ You can read the documentation [here](https://orpc.dev).
5252
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
5353
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
5454
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
55+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
5556
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
5657
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
5758
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).

0 commit comments

Comments
 (0)