@pylonsync/react is the React-first client. It wraps @pylonsync/sync with useSyncExternalStore-backed hooks so your components re-render automatically when entity data changes.
Install
@pylonsync/sync transitively; you don’t need to install it directly.
Configure once
In your app entry:localStorage under pylon_token (or pylon:<appName>:token if you set a custom app name).
Hooks
useQuery
Live-updating list of entity rows. Re-renders when the local store changes (after server pushes, optimistic mutations, or hydration).
useQueryOne
Single row by id:
useInfiniteQuery
Cursor-paginated list with loadMore:
useMutation
Call a server function with typed args:
useEntityMutation:
useSession
Live-updating auth context:
session mirrors AuthContext and re-renders on sign-in / sign-out / tenant switch.
useSearch
Full-text search with live facet counts (requires the search plugin enabled per-entity):
useAggregate
Live-updating count/sum/avg/min/max/groupBy:
useShard
Connect to a tick-driven multiplayer shard:
Auth helpers
Standalone async functions for sign-in flows — they update the storage adapter and then anyuseSession consumers re-render:
Direct (non-synced) calls
For one-shot fetches that bypass the sync engine (e.g. server-rendered pages, scripts):useEntityMutation instead if you want optimistic UI.
Streaming functions
For functions that stream output (AI chat, live data):Files
Typed client (codegen)
Afterpylon codegen client manifest.json --out client.ts, you get a typed wrapper:
SSR / hydration
For Next.js or any SSR framework, fetch on the server and hydrate on the client:@pylonsync/next.
React Native
@pylonsync/react’s hooks work in React Native too, but the storage adapter (localStorage) doesn’t. Use @pylonsync/react-native instead — it has the AsyncStorage bridge and SQLite-backed persistence.
Performance
- Hooks use
useSyncExternalStoreso React batches re-renders correctly. - The local store keeps an in-memory snapshot per entity;
useQueryreads are O(1). - Optimistic mutations fire a single re-render across all subscribed components.
- WebSocket updates batch into one render per server tick to avoid render thrashing.
Common pitfalls
- Forgetting to call
configureClientbefore mounting — hooks throw if no base URL is set. - Using
useQueryoutside a sync engine — without<PylonProvider>(or the implicit default), the hook can’t subscribe. Add the provider once at the app root. - Holding stale data in
wherefilters —useQueryre-runs the filter on every store notify, so changingwheretriggers a re-fetch correctly. But if you derivewherefrom React state, memoize it withuseMemoto avoid object identity churn.