MCPcopy Index your code
hub / github.com/Colonel-Sandvich/trpc-vue-query

github.com/Colonel-Sandvich/trpc-vue-query @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
28 symbols 90 edges 25 files 0 documented · 0%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

trpc-vue-query

A simple package to bridge the gap between TRPC and TanStack Query for Vue much like how TRPC has their own in-house React Query Integration

Why this package?

If you're using @tanstack/vue-query then you might know that working with query keys and query functions can sometimes become cumbersome. A lead maintainer of Tanstack Query, TkDodo, has said that "Separating QueryKey from QueryFunction was a mistake".

So this package tightly couples your keys and functions leading to brilliant DX :rocket:

Before:

const currentUserQuery = queryOptions({
  queryKey: ["user", "current"],
  queryFn: () => trpc.user.current.query(),
});

const { data } = useQuery(currentUserQuery);

const { mutateAsync } = useMutation({
  mutationFn: (input: UnwrapRef<typeof form>) => trpc.user.signUp.mutate(input),
  onSuccess: async () => {
    await useQueryClient().invalidateQueries({
      queryKey: currentUserQuery.queryKey,
    });
    await navigateTo("/onboarding");
  },
});

After:

const { data } = useClient().user.current.useQuery();

const { mutateAsync } = useClient().user.signUp.useMutation({
  onSuccess: async () => {
    await useClient().user.current.invalidate();
    await navigateTo("/onboarding");
  },
});

Install

pnpm i @colonel-sandvich/trpc-vue-query

Setup (Vue)

1. Plug in the plugin

// main.ts
import { TrpcVueQueryPlugin } from "@colonel-sandvich/trpc-vue-query";
import { VueQueryPlugin } from "@tanstack/vue-query";
import { httpBatchLink } from "@trpc/client";
import { createApp } from "vue";
import App from "./src/App.vue";
import { trpc } from "your-path-to-trpc-client";
// ^ See https://trpc.io/docs/client/vanilla/setup#3-initialize-the-trpc-client

export const app = createApp(App);

app
  .use(VueQueryPlugin) // Make sure {@tanstack/vue-query}'s plugin goes first
  .use(TrpcVueQueryPlugin, {
    trpcClient: trpc,
  })
  .mount("#app");

2. Make a composable

// src/composables/useClient.ts
import { TrpcVueClient, clientKey } from "@colonel-sandvich/trpc-vue-query";
import { inject } from "vue";
import type { AppRouter } from "your-path-to-trpc-app-router-type";

export function useClient() {
  return inject(clientKey) as TrpcVueClient<AppRouter>;
}

Setup (Nuxt)

0. Setup @tanstack/vue-query for Nuxt if you haven't already

// src/plugins/01.vueQueryPlugin.ts

// Important that this plugin comes before the `02.clientPlugin` since that has this plugin as a dependency
export default defineNuxtPlugin((nuxt) => {
  nuxt.vueApp.use(VueQueryPlugin);

  // Below is for SSR. Remove if you don't need this
  // Provided from TanStack Query docs: https://tanstack.com/query/v5/docs/vue/guides/ssr
  const vueQueryState = useState<DehydratedState | null>("vue-query");

  if (process.server) {
    nuxt.hooks.hook("app:rendered", () => {
      vueQueryState.value = dehydrate(queryClient);
    });
  }

  if (process.client) {
    nuxt.hooks.hook("app:created", () => {
      hydrate(queryClient, vueQueryState.value);
    });
  }
});

1. Make a plugin

// src/plugins/02.clientPlugin.ts

export default defineNuxtPlugin(() => {
  const trpc = createTRPCProxyClient<AppRouter>({
    links: [
      httpBatchLink({
        url: "/api/trpc",
        headers: useRequestHeaders(),
        fetch: customFetchWrapper(), // Crucial for SSR
      }),
    ],
  });

  const client = createTrpcVueClient(trpc, useQueryClient());

  return {
    provide: {
      client,
    },
  };
});

2. Make a composable

// src/composables/useClient.ts

export const useClient = () => {
  return useNuxtApp().$client;
};

You're Done!

Go check out /examples to see some basic uses.

Quickstart for testing examples/vue-minimal

pnpm i Anywhere

cd examples/vue-minimal

pnpm dev

If ports 3000 (client) and 3001 (server) are available then you should up and running

Goals of the project

  • [x] Easier integration with Vue and Nuxt
  • [ ] Feature parity with TRPC's React Query (or at least as much as is possible with Vue Query)
  • [ ] Subscriptions
  • [ ] Documentation

Contributing

Please please please absolutely make an issue or PR for any bugs or feature requests, I highly encourage it.

Acknowledgments

Big thanks to Robert Soriano for his trpc-nuxt package that inspired this package.

Star History

Star History Chart

Core symbols most depended-on inside this repo

getQueryKeyInternal
called by 7
src/helpers.ts
pathToString
called by 3
src/helpers.ts
cloneDeepUnref
called by 3
src/utils.ts
createTrpcVueClient
called by 2
src/client.ts
createAugmentedClient
called by 1
src/functions.ts
getPath
called by 1
src/apiHandler.ts
cloneDeep
called by 1
src/utils.ts
isPlainObject
called by 1
src/utils.ts

Shape

Function 28

Languages

TypeScript100%

Modules by API surface

src/functions.ts9 symbols
src/utils.ts4 symbols
src/apiHandler.ts4 symbols
examples/vue-playground/client/src/composables/useClient.ts3 symbols
src/helpers.ts2 symbols
src/customFetch.ts2 symbols
src/vuePlugin.ts1 symbols
src/client.ts1 symbols
examples/vue-playground/server/trpc.ts1 symbols
examples/nuxt-starter/src/composables/useClient.ts1 symbols

For agents

$ claude mcp add trpc-vue-query \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact