syncore-react-realtime

Syncore React Realtime

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "syncore-react-realtime" with this command: npx skills add jpsaud501/syncore/jpsaud501-syncore-syncore-react-realtime

Syncore React Realtime

Use this skill when wiring Syncore into React apps or debugging hook inference, watch lifecycle, or result propagation.

Documentation Sources

Read these first:

  • packages/react/src/index.tsx

  • packages/react/AGENTS.md

  • packages/platform-web/src/react.tsx

  • packages/platform-node/src/ipc-react.tsx

  • packages/platform-expo/src/react.tsx

  • packages/next/src/index.tsx

  • docs/quickstarts/react-web.md

  • docs/quickstarts/expo.md

  • docs/quickstarts/electron.md

  • docs/quickstarts/next-pwa.md

  • examples/electron/src/renderer/App.tsx

  • examples/expo/App.tsx

  • examples/next-pwa/app/bookmarks-screen.tsx

Instructions

Provider First

Every hook depends on SyncoreProvider or a platform wrapper that mounts it for you.

Raw provider:

import { SyncoreProvider } from "syncorejs/react";

<SyncoreProvider client={client}>{children}</SyncoreProvider>;

Common wrapper providers in app code are:

  • SyncoreBrowserProvider from syncorejs/browser/react

  • SyncoreElectronProvider from syncorejs/node/ipc/react

  • SyncoreExpoProvider from syncorejs/expo/react

  • SyncoreNextProvider from syncorejs/next

If no provider is present, hooks will throw.

useQuery

useQuery is the core reactive read API. It returns undefined while the first result is still loading.

import { useQuery } from "syncorejs/react"; import { api } from "../syncore/_generated/api";

function Tasks() { const tasks = useQuery(api.tasks.list) ?? []; return <pre>{JSON.stringify(tasks, null, 2)}</pre>; }

Pass "skip" as the second argument to suppress the subscription entirely:

import { skip, useQuery } from "syncorejs/react";

const results = useQuery( api.notes.search, searchText.trim() ? { query: searchText.trim() } : skip );

useMutation And useAction

Mutations and actions return callable functions with typed args and results inferred from the reference.

import { useAction, useMutation } from "syncorejs/react"; import { api } from "../syncore/_generated/api";

const createTask = useMutation(api.tasks.create); const exportTasks = useAction(api.tasks.exportTasks);

Prefer Inference Over Manual Generics

Preferred:

const todos = useQuery(api.todos.list) ?? []; const createTodo = useMutation(api.todos.create);

Fallbacks with manual generics should be treated as a signal to inspect shared typing, not as the ideal pattern.

Watch Lifecycle Matters

Syncore React hooks are thin wrappers over SyncoreClient.watchQuery(...) . When changing React bindings:

  • preserve stable args behavior

  • dispose watches when refs or args change

  • keep React types aligned with SyncoreClient

useQueries

Use useQueries when a keyed batch of query subscriptions is the right shape for the view:

const data = useQueries([ { key: "tasks", reference: api.tasks.list }, { key: "notes", reference: api.notes.list } ]);

Represent the result as keyed query state, not as a substitute for ordinary component composition.

useQueries is intentionally less strongly typed than useQuery , useMutation , and useAction . Prefer the single-hook APIs when they fit the component shape better.

Examples

Basic App Wiring

import { SyncoreProvider, useMutation, useQuery } from "syncorejs/react"; import type { SyncoreClient } from "syncorejs"; import { api } from "../syncore/_generated/api";

export function App({ client }: { client: SyncoreClient }) { return ( <SyncoreProvider client={client}> <Todos /> </SyncoreProvider> ); }

function Todos() { const todos = useQuery(api.todos.list) ?? []; const createTodo = useMutation(api.todos.create);

return ( <div> <button onClick={() => void createTodo({ title: "Ship local-first DX" })}> Add </button> {todos.map((todo) => ( <div key={todo._id}>{todo.title}</div> ))} </div> ); }

Platform Wrapper Example

import { SyncoreNextProvider } from "syncorejs/next";

const createWorker = () => new Worker(new URL("./syncore.worker", import.meta.url), { type: "module" });

export function AppSyncoreProvider({ children }: { children: React.ReactNode; }) { return ( <SyncoreNextProvider createWorker={createWorker}> {children} </SyncoreNextProvider> ); }

Loading State

function Notes() { const notes = useQuery(api.notes.list); if (notes === undefined) { return <div>Loading...</div>; } return <pre>{JSON.stringify(notes, null, 2)}</pre>; }

Best Practices

  • Always mount hooks under SyncoreProvider or a platform wrapper provider

  • Prefer useQuery(api.foo.bar) without manual generics when typing supports it

  • Handle undefined loading state explicitly

  • Use skip instead of hand-rolled conditional subscriptions

  • Keep hooks thin over SyncoreClient rather than duplicating runtime behavior

  • Prefer platform wrapper providers in app shells and the raw provider in low-level tests or custom integrations

  • When editing hook types, validate inference and watch cleanup together

Common Pitfalls

  • Calling hooks outside a Syncore provider

  • Treating manual generics as the desired steady state for app code

  • Forgetting that query subscriptions must be cleaned up when args or refs change

  • Narrowing React-facing types more than the core client allows

  • Using useQueries where better-typed independent hooks would be clearer

References

  • packages/react/src/index.tsx

  • packages/react/AGENTS.md

  • packages/platform-web/src/react.tsx

  • packages/platform-node/src/ipc-react.tsx

  • packages/platform-expo/src/react.tsx

  • packages/next/src/index.tsx

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

syncore-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
General

syncore-platform-adapters

No summary provided by upstream source.

Repository SourceNeeds Review
General

syncore

No summary provided by upstream source.

Repository SourceNeeds Review