Skip to main content

Limitations and Trade-offs

Understand the runtime costs, deliberate constraints, and unsupported cases before adopting the module.

Better Convex Nuxt removes integration work by choosing a defined lifecycle. Those choices have costs.

SSR plus live data performs two stages

The default query performs:

  1. An HTTP query during SSR.
  2. A WebSocket subscription in the browser.

Both stages serve a purpose. The first produces initial HTML; the second keeps data live. They may appear as two query executions in the Convex dashboard and both contribute to application work.

Disable SSR for browser-only data:

ts
await useConvexQuery(api.notifications.list, {}, { server: false })

Disable the subscription for a snapshot:

ts
await useConvexQuery(api.reports.snapshot, {}, { subscribe: false })

Better Auth is the maintained auth integration

The built-in authentication runtime is designed around Better Auth and @convex-dev/better-auth. Another provider requires an application-owned integration or another library.

Set auth: false when the application does not use authentication. This removes auth-only plugins, proxy handlers, middleware, and Better Auth runtime code from the build graph.

Product authorization remains yours

The module can determine whether a Convex identity is available. It cannot know whether that identity may edit a project, administer an organization, or read a document.

Enforce those rules inside Convex functions. Route middleware and conditional components are UX controls.

Schema-changing auth plugins require more setup

Better Auth plugins such as organizations, admin, and API keys can change the component schema and client API. They require matching server configuration, schema generation, local component registration, and a typed client definition.

The module does not make an arbitrary Better Auth plugin compatible automatically.

The raw Convex client is not public

useConvex() returns exactly query, mutation, action, and onUpdate. It does not expose setAuth, clearAuth, connectionState, or close.

This constraint lets the runtime replace an identity-scoped client without leaving application code with a closed reference. Use useConvexConnectionState() for connection observation.

Query state is app-instance state

Shared query definitions are shared within one Nuxt application instance. They are not a cross-request server cache and never permit data reuse across identities.

Convex owns server-backed query data. Use Pinia or local state for UI-only concerns, not as a mirror of Convex entities.

Awaited live queries have a first-result timeout

An awaited subscribe-mode query waits up to 10 seconds for its first WebSocket result by default. Set convex.defaults.waitTimeoutMs to another non-negative value. 0 waits indefinitely.

An indefinite wait can also make navigation wait indefinitely. Use it only when the surrounding UX has an explicit recovery path.

Exact versions are intentional

The 0.6.1 release pins Convex, Better Auth, and @convex-dev/better-auth peer versions. This makes lifecycle and security behavior testable, but requires coordinated dependency upgrades.

Read release compatibility before overriding versions.