9.9 KiB
| name | description | metadata | ||
|---|---|---|---|---|
| powersync-js-vue | PowerSync Vue and Nuxt integration — composables, plugin setup, Kysely ORM, and diagnostics panel |
|
PowerSync Vue & Nuxt
Load this when building a Vue app or Nuxt app with PowerSync. Always load
powersync-js.mdfirst.
Table of Contents
Vue-specific integration for the PowerSync JavaScript SDK. Use this reference alongside references/sdks/powersync-js.md when building Vue apps or Nuxt apps.
| Resource | Description |
|---|---|
| Vue Composables Reference | Full Vue composables guide, consult for details beyond the inline examples. |
| Vue SDK API Reference | Full API reference for @powersync/vue, consult only when the inline examples don't cover your case. |
| Nuxt Integration Guide | Full Nuxt setup guide. |
| Nuxt Module API Reference | API reference for @powersync/nuxt. |
Vue
1. Install
# npm (v7+ installs peer dependencies automatically)
npm install @powersync/vue@latest
# pnpm (must install peer dependencies explicitly)
pnpm add @powersync/vue@latest @powersync/web@latest @journeyapps/wa-sqlite@latest
2. Plugin Setup
import { createPowerSyncPlugin } from '@powersync/vue';
import { PowerSyncDatabase } from '@powersync/web';
import { AppSchema } from './AppSchema';
import { PowerSyncConnector } from './PowerSyncConnector';
import { createApp } from 'vue';
import App from './App.vue';
const db = new PowerSyncDatabase({
database: { dbFilename: 'app.db' },
schema: AppSchema
});
const connector = new PowerSyncConnector();
db.connect(connector);
const app = createApp(App);
app.use(createPowerSyncPlugin({ database: db }));
app.mount('#app');
Composables
In a standalone Vue app, composables are imported from @powersync/vue. In Nuxt, all composables are auto-imported — no import statement is needed.
useQuery
Reactive query — re-renders the component automatically when underlying data changes.
import { useQuery } from '@powersync/vue'; // omit import in Nuxt
const { data: lists, isLoading, isFetching, error } = useQuery(
'SELECT * FROM lists ORDER BY created_at DESC'
);
With parameters (parameters are reactive — can be a ref or computed):
const { data: todos } = useQuery(
'SELECT * FROM todos WHERE list_id = ?',
[listId]
);
Return shape: { data: Ref<RowType[]>, isLoading: Ref<boolean>, isFetching: Ref<boolean>, error: Ref<Error | undefined> }.
For advanced watch query features including incremental updates and differential results, see Live Queries / Watch Queries.
useStatus
Reactive connectivity status. Same shape as the React useStatus hook — see references/sdks/powersync-js.md for the full status field reference.
import { useStatus } from '@powersync/vue'; // omit import in Nuxt
const status = useStatus();
// status.connected, status.hasSynced, status.lastSyncedAt, etc.
usePowerSync
Access the PowerSyncDatabase instance directly for imperative operations.
import { usePowerSync } from '@powersync/vue'; // omit import in Nuxt
import { v4 as uuid } from 'uuid';
const powersync = usePowerSync();
await powersync.value.execute(
'INSERT INTO lists (id, created_at, name, owner_id) VALUES (?, ?, ?, ?)',
[uuid(), new Date().toISOString(), 'My List', currentUserId]
);
usePowerSync() returns a Ref<AbstractPowerSyncDatabase> — access the database via .value.
Setup Context Requirement
usePowerSync, useQuery, and useStatus all rely on Vue's inject() internally and must be called at the top level of a <script setup> block (or the synchronous setup() function). They must not be called inside nested functions, async functions, event handlers, or lifecycle hooks.
<script setup>
import { usePowerSync } from '@powersync/vue';
// ✅ Correct — called at the top level of setup
const powerSync = usePowerSync();
const handleClick = async () => {
// ✅ Use the ref returned from the top-level call
const result = await powerSync.value.getAll('SELECT * FROM lists');
console.log(result);
};
// ❌ Wrong — usePowerSync() called inside a nested function
const handleClickBad = async () => {
const result = await usePowerSync().value.getAll('SELECT * FROM lists');
};
</script>
Calling these composables outside of a setup context throws an error. If you need to access the PowerSync database outside a component (e.g. in a store or utility module), export the database instance directly instead of using the composable.
Example Component
<script setup lang="ts">
import { usePowerSync, useQuery, useStatus } from '@powersync/vue';
const powersync = usePowerSync();
const { data: lists, isLoading } = useQuery('SELECT * FROM lists ORDER BY created_at DESC');
const status = useStatus();
</script>
<template>
<div>
<p>Status: {{ status.connected ? 'Connected' : 'Offline' }}</p>
<p v-if="isLoading">Loading...</p>
<ul v-else>
<li v-for="list in lists" :key="list.id">{{ list.name }}</li>
</ul>
</div>
</template>
Nuxt
Alpha:
@powersync/nuxtis currently in Alpha. APIs and behavior may change.
@powersync/nuxt is a Nuxt module that wraps @powersync/vue and re-exports all its composables. It also adds a Nuxt Devtools integration with a PowerSync diagnostics panel.
PowerSync is tailored for client-side applications. Nuxt evaluates plugins server-side unless you use the .client.ts suffix. The PowerSync Web SDK requires browser APIs not available in Node.js — it performs no-ops in Node.js rather than throwing errors, but no data is available during SSR. Always create your PowerSync plugin as plugins/powersync.client.ts.
1. Install
# npm (v7+ installs peer dependencies automatically)
npm install @powersync/nuxt@latest
# pnpm (must install peer dependencies explicitly)
pnpm add @powersync/nuxt@latest @powersync/vue@latest @powersync/web@latest
2. nuxt.config.ts
Add @powersync/nuxt to the modules array and include the required Vite configuration:
export default defineNuxtConfig({
modules: ['@powersync/nuxt'],
vite: {
optimizeDeps: {
exclude: ['@powersync/web']
},
worker: {
format: 'es'
}
}
});
3. Create the Plugin
Create plugins/powersync.client.ts. The .client.ts suffix ensures this only runs in the browser.
import { NuxtPowerSyncDatabase, createPowerSyncPlugin } from '@powersync/nuxt';
import { AppSchema } from '~/powersync/AppSchema';
import { PowerSyncConnector } from '~/powersync/PowerSyncConnector';
export default defineNuxtPlugin({
async setup(nuxtApp) {
const db = new NuxtPowerSyncDatabase({
database: {
dbFilename: 'my-app.sqlite'
},
schema: AppSchema
});
const connector = new PowerSyncConnector();
await db.init();
await db.connect(connector);
const plugin = createPowerSyncPlugin({ database: db });
nuxtApp.vueApp.use(plugin);
}
});
Using Composables
All @powersync/vue composables (usePowerSync, useQuery, useStatus) are auto-imported in Nuxt — no import statement is needed in components or composables.
<script setup lang="ts">
// No imports needed — composables are auto-imported by @powersync/nuxt
const powersync = usePowerSync();
const { data: lists, isLoading } = useQuery('SELECT * FROM lists ORDER BY created_at DESC');
const status = useStatus();
</script>
The same setup context requirement as standalone Vue applies — call composables at the top level of <script setup>, not inside nested or async functions.
Kysely ORM (Optional)
The module optionally exposes a usePowerSyncKysely() composable for type-safe query building.
Install the driver:
npm install @powersync/kysely-driver@latest
Enable it in nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@powersync/nuxt'],
powersync: {
kysely: true
},
vite: {
optimizeDeps: {
exclude: ['@powersync/web']
},
worker: {
format: 'es'
}
}
});
Use in components — usePowerSyncKysely is auto-imported. Import only your schema's Database type for full type safety:
import { type Database } from '~/powersync/AppSchema';
const db = usePowerSyncKysely<Database>();
const lists = await db.selectFrom('lists').selectAll().execute();
Diagnostics Panel
@powersync/nuxt includes a PowerSync diagnostics panel that shows sync status, local data, bucket contents, config, and logs. Must be explicitly enabled.
Enable in nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@powersync/nuxt'],
powersync: {
useDiagnostics: true
},
vite: {
optimizeDeps: {
exclude: ['@powersync/web']
},
worker: {
format: 'es'
}
}
});
When useDiagnostics: true is set, NuxtPowerSyncDatabase automatically extends the schema with the diagnostics schema, sets up recording and logging, and stores the connector internally. No changes to the plugin file are needed.
Access the inspector:
- Nuxt Devtools: open browser Devtools and look for the PowerSync tab
- Direct URL: navigate to
http://localhost:3000/__powersync-inspector
Known Issues
Tailwind CSS conflict
PowerSync Inspector uses unocss as a transitive dependency, which conflicts with Tailwind CSS. If you use Tailwind, add the following to nuxt.config.ts:
export default defineNuxtConfig({
unocss: {
autoImport: false
}
});