Skip to main content

Convex Svelte

Convex Svelte is the client library enabling your Svelte application to interact with your Convex backend. It enhances the ConvexClient with declarative subscriptions for Svelte 5, so your frontend code can:

  1. Receive live updates to your queries with automatic reactivity
  2. Call your mutations and actions
  3. Paginate through large datasets
  4. Authenticate users
  5. Server-side render data in SvelteKit
Source & issues

Source: get-convex/convex-svelte.


Found a bug or have a feature request? Open an issue in its issue tracker.

Follow the Svelte Quickstart to get started, or read on for the full setup.

Installation

Install the Convex client and server library:

npm install convex convex-svelte

Svelte doesn't like referencing code outside of src/, so customize the Convex functions directory. Create a convex.json in your project root:

convex.json
{
"functions": "src/convex/"
}

Set up a Convex dev deployment:

npx convex dev

This will prompt you to log in, create a project, and save your deployment URLs. It also creates a src/convex/ folder for your backend API functions.

Setup

Call setupConvex() once in a root layout component (e.g. +layout.svelte). This initializes a ConvexClient and stores it in Svelte context so child components can access it. The client is app-scoped: it stays open for the lifetime of the app (remounts and HMR reuse the same connection) and supports a single deployment URL. For explicit teardown — e.g. in tests — call closeConvex().

src/routes/+layout.svelte
<script lang="ts">
import { setupConvex } from "convex-svelte";
import { PUBLIC_CONVEX_URL } from "$env/static/public";

const client = setupConvex(PUBLIC_CONVEX_URL);
</script>

setupConvex() returns the ConvexClient instance, which you can use directly in the layout for mutations or actions (e.g. an auth nav bar). In child components and .ts files, use getConvexClient() to retrieve it — see Client access.

You can pass ConvexClientOptions as the second argument to configure the ConvexClient.

Non-SvelteKit usage

If you're using plain Vite + Svelte (no SvelteKit), replace $env/static/public with import.meta.env.VITE_CONVEX_URL and set VITE_CONVEX_URL in your .env file.

Fetching data

Use useQuery() to subscribe to a Convex query with automatic real-time updates. When the data changes on the server, your component re-renders automatically.

src/routes/+page.svelte
<script lang="ts">
import { useQuery } from "convex-svelte";
import { api } from "../convex/_generated/api.js";

const messages = useQuery(api.messages.list, () => ({ searchWords: [] }));
</script>

{#if messages.isLoading}
Loading...
{:else if messages.error != null}
failed to load: {messages.error.toString()}
{:else}
<ul>
{#each messages.data as message}
<li>
<span>{message.author}</span>
<span>{message.body}</span>
</li>
{/each}
</ul>
{/if}

See Queries, Mutations & Actions for the full reactive API — query options, skipping, mutations, actions, optimistic updates, pagination, and accessing the client outside of components.

Next steps