Guide

Quick start

A server route and a component, each talking to its own PGlite.

On the server

usePGlite() is auto-imported in your server routes. It returns the instance, creating it on first use:

server/api/todos.get.ts
export default defineEventHandler(async () => {
  const pg = await usePGlite()
  await pg.exec('CREATE TABLE IF NOT EXISTS todos (id serial PRIMARY KEY, title text)')
  const { rows } = await pg.query<{ id: number; title: string }>('SELECT * FROM todos')
  return rows
})

Its data lives in .data/pglite under your project. Table setup like the one above belongs in the config file's init, which runs once per instance.

In the browser

Enable the client side and add a config file with the live extension, which the live-query composables need:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-pglite'],
  pglite: {
    client: { enabled: true },
  },
})
app/pglite.config.ts
import { live } from '@electric-sql/pglite/live'

export default definePGliteClientConfig({
  dataDir: 'idb://my-app',
  clientExtensions: { live },
  init: async (pg) => {
    await pg.exec('CREATE TABLE IF NOT EXISTS todos (id serial PRIMARY KEY, title text)')
  },
})

Then query it from a component. The database runs in the browser, so the component is client-only:

app/components/Todos.client.vue
<script setup lang="ts">
const { rows: todos } = useLiveQuery<{ id: number; title: string }>(
  'SELECT * FROM todos ORDER BY id',
)

async function add(title: string) {
  const pg = await usePGlite()
  await pg.query('INSERT INTO todos (title) VALUES ($1)', [title])
}
</script>

<template>
  <ul>
    <li v-for="todo in todos" :key="todo.id">{{ todo.title }}</li>
  </ul>
  <button @click="add('Try PGlite')">Add</button>
</template>

This very page runs the same setup. Add a few todos, then reload or open another tab: they are stored in your browser and the list follows every change.

app/pglite.config.ts
import { live } from '@electric-sql/pglite/live'

export default definePGliteClientConfig({
  dataDir: 'idb://nuxt-pglite-docs',
  clientExtensions: { live },
  init: async (pg) => {
    await pg.exec(`CREATE TABLE IF NOT EXISTS todos (
      id serial PRIMARY KEY,
      title text NOT NULL,
      done boolean NOT NULL DEFAULT false
    )`)
  },
})

Next steps

Server

Extensions, init, data directories and per-environment settings.

Development socket

Point pg, Drizzle, drizzle-kit or psql at the development database.

Client

The in-browser instance, live queries and a SQL playground.

DevTools

Inspect the instances, run SQL and your own actions.