The Vue adapter works differently from React in one key way: instead of a <api.Provider> component, you register pyrpc.plugin on your Vue app. Everything else (typed queries, mutations, reactive args) follows Vue 3 Composition API conventions.
Project layout
fastapi-vue/
server/
main.py ← FastAPI app (same as React example)
pyrpc.json
client/
src/
pyrpc.ts ← createPyrpcVue setup
main.ts ← createApp().use(pyrpc.plugin)
App.vue ← createQuery / createMutation callsClient setup
// src/pyrpc.ts
import { createPyrpcVue } from "@pyrpc/vue"
import type { Types } from "@pyrpc/types"
export const pyrpc = createPyrpcVue<Types>({
baseUrl: import.meta.env.VITE_API_URL ?? "http://localhost:8000",
})// src/main.ts
import { createApp } from "vue"
import App from "./App.vue"
import { pyrpc } from "./pyrpc"
createApp(App).use(pyrpc.plugin).mount("#app")Using the composables
<!-- src/App.vue -->
<script setup lang="ts">
import { ref } from "vue"
import { pyrpc } from "./pyrpc"
const name = ref("")
// @rpc.query → createQuery
const { data: greeting, isPending } = pyrpc.read_root.createQuery()
// pass reactive args as a getter so they re-fetch on change
const { data: item } = pyrpc.read_item.createQuery(
() => ({ item_id: 42, q: "test" })
)
// @rpc.mutation → createMutation
const createItem = pyrpc.create_item.createMutation()
const handleCreate = () => {
if (name.value.trim()) {
createItem.mutate({ name: name.value, description: `Item: ${name.value}` })
name.value = ""
}
}
</script>
<template>
<div>
<p v-if="isPending">Loading…</p>
<pre v-else>{{ JSON.stringify(greeting) }}</pre>
<pre>{{ JSON.stringify(item) }}</pre>
<input v-model="name" placeholder="Item name" />
<button @click="handleCreate" :disabled="createItem.isPending.value">
{{ createItem.isPending.value ? "Creating…" : "Create" }}
</button>
<pre v-if="createItem.isSuccess.value">
{{ JSON.stringify(createItem.data.value) }}
</pre>
</div>
</template>Key differences from React
Plugin vs Provider. Vue uses app.use(pyrpc.plugin) instead of a JSX Provider component. The plugin registers TanStack Vue Query under the hood.
Reactive values. Reactive data comes back as Ref values. Access them with .value in <script>, directly in templates.
Reactive args. Pass query args as a getter function (() => ({ ... })) so TanStack Vue Query tracks reactive dependencies and re-fetches automatically.
Run it
# Terminal 1 cd server && uv add pyrpc-core[fastapi] && pyrpc dev # Terminal 2 cd client && npm install && npm run dev
Open http://localhost:5173.

pyRPC