Release candidate — 1.0.0-rc.7
StitchAPI

SWR

useStitchSWR runs a stitch as an SWR fetcher, so SWR owns caching and revalidation while the stitch stays typed, validated, and traced.

Use @stitchapi/swr when your app is already on SWR and you want a stitch as the fetcher. SWR keeps owning caching, deduping, and revalidation; the stitch stays the typed, validated, traced call. There is no @stitchapi/query-core here — SWR is the store.

If you'd rather StitchAPI own the lifecycle directly — especially streaming, which SWR doesn't model — reach for useStitchStream in @stitchapi/react instead.

Example

Install the adapter alongside core, SWR, and React:

npm install @stitchapi/swr@rc stitchapi@rc swr react

stitchapi, swr, and react are peer dependencies.

useStitchSWR

Pass a stitch and its input; get SWR's own response back (data, error, isLoading, isValidating, mutate). The cache key is the stitch's name plus the input, so two components calling the same stitch with the same input dedupe to one request.

import { useStitchSWR } from '@stitchapi/swr';
import { stitch } from 'stitchapi';

const getUser = stitch({
    baseUrl: 'https://api.example.com',
    path: '/users/{id}',
});

function Profile({ id }: { id: string }) {
    const { data, error, isLoading } = useStitchSWR(getUser, {
        params: { id },
    });
    if (isLoading) return <Spinner />;
    if (error) return <Retry />;
    return <h1>{data?.name}</h1>;
}

Pass SWR options as the third argument — they go straight through:

useStitchSWR(getUser, { params: { id } }, { refreshInterval: 5000 });

Conditional fetching & mutate

swrKey(stitch, input) returns the cache key, so you can use SWR's null-key conditional pattern or target a mutate:

import { swrKey } from '@stitchapi/swr';
import useSWR from 'swr';

// Skip the request until `id` exists.
const { data } = useSWR(id ? swrKey(getUser, { params: { id } }) : null, () =>
    getUser({ params: { id } }),
);

The key is [name, input], but never your raw input. name is the stitch's name ?? path ?? url ?? 'stitch' (so two nameless stitches on different paths can't collide on one entry), and the input is sanitised: the runtime-only signal and onProgress are dropped — onProgress changes identity every render, which would refetch forever — and the values of secret-bearing headers are replaced with [redacted]. The header itself stays, so a call that legitimately varies by accept-language still gets its own entry.

Secret headers are the fixed denylist (authorization, proxy-authorization, cookie, set-cookie, x-api-key, x-auth-token), any *-token / *-api-key spelling, and anything secrets.register has widened — the same rule @stitchapi/query-core applies to every other binding's query key, so a credential redacted in a React app is redacted here too. This matters because SWR keys are persisted by cache providers and shown in devtools: a token in one outlives the request.

useStitchSWR is for when SWR already owns your view state and you want a stitch as the fetcher. For StitchAPI to own the lifecycle — and for streaming — use useStitch / useStitchStream. The same split applies to TanStack Query and RTK Query.

See also

On this page