Skip to content

powersync-community/nextjs-sync-stream

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Next.js sync-stream reproduction

Minimal Next.js + @powersync/web app for testing parameterised sync streams across local dev, a local production build, and a deployed build.

A thread page subscribes to the thread_runtime_data stream with useSyncStream({ name, parameters: { thread_id }, ttl: 0 }) and re-subscribes on every navigation (client/src/lib/powersync/hooks.ts). A second stream, threads_list, is auto_subscribe: true and acts as the control. A diagnostics panel on every page shows sdkVersion, connected, hasSynced, and the live syncStreams list.

Auth runs in the browser via Supabase anonymous sign-in (see Auth).

Versions: @powersync/web@1.39.0, @powersync/react@1.10.0, @journeyapps/wa-sqlite@1.7.2, PowerSync service 1.21.0.

backend/    Postgres + PowerSync service (docker compose), seeded with 3 threads
client/     Next.js 16 App Router client
cloud/      PowerSync Cloud config for the deployed setup (same streams)

Run

Run everything locally, or point the client at a remote Supabase + PowerSync combo. Either way the client env vars are the same three below (see Auth).

Local

Backend (local PowerSync at http://localhost:8080):

cd backend
docker compose up

Client:

cd client
cp .env.local.template .env.local   # then fill in the PowerSync + Supabase values
pnpm install

pnpm dev                   # local dev
pnpm build && pnpm start   # local production build

Remote

Use a hosted PowerSync instance and Supabase project: set the env vars to their public URLs and deploy client/, e.g. on Vercel with Root Directory = client.

Auth

Authentication runs entirely in the browser, so it works the same in all three run modes. On first connect the client signs in anonymously with Supabase (supabase.auth.signInAnonymously()) and returns the Supabase-issued JWT to PowerSync from fetchCredentials (client/src/lib/powersync/connector.ts). There is no app-minted token and no shared signing secret.

Required client env vars (all NEXT_PUBLIC_, so they reach the browser):

Env var What
NEXT_PUBLIC_POWERSYNC_URL PowerSync endpoint the browser connects to
NEXT_PUBLIC_SUPABASE_URL Supabase project URL
NEXT_PUBLIC_SUPABASE_ANON_KEY Supabase anon / publishable key (safe to expose)

Two things must be set up outside the client:

  1. Enable anonymous sign-ins in Supabase (Auth → Providers → Anonymous).
  2. Configure PowerSync to verify Supabase JWTs (backend/powersync.yaml): point PS_SUPABASE_JWKS_URI at your project's JWKS endpoint and keep authenticated in the audience list (that is the aud Supabase puts on its tokens, anonymous users included).

What to look for

Open a thread, navigate between threads, and hard-reload a thread page.

  • Working: messages load and syncStreams lists thread_runtime_data with the current thread_id after every navigation and after a reload.
  • Reproduced: the threads list populates (control stream works) but thread pages show no messages and thread_runtime_data never appears in syncStreams.
  • Threads list empty or connected: false: connection/auth problem with the setup, not the stream issue — check NEXT_PUBLIC_POWERSYNC_URL, the Supabase env vars, and that the backend is configured to verify Supabase JWTs.

This reproduction was built with the assistance of AI (Claude). Manually reviewed and validated.

About

Minimal Next.js + @powersync/web repro: parameterised sync stream via useSyncStream across local dev, production build, and deployed (Vercel) modes

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages