Core · Library

Reactive Queries

Subscribe once. Your UI stays current, automatically, everywhere.

Your UI should always show what is actually true. Not what was true when the page loaded. Not what was true before the user switched tabs and came back. Just the truth, right now.

sp00ky turns any query into a live subscription. You write it once, your component reads the result, and sp00ky quietly keeps it fresh as data changes. No refetch buttons, no focus listeners, no "pull to refresh" that the user has to discover on their own.

The old way, and why it gets tiring

Keeping a UI in sync with a live database is one of those problems that always starts small and ends up everywhere. First you add a refetch, then a polling interval, then a refresh-on-focus, then a WebSocket, then a reducer that patches the cache when the socket says something changed, and then a small book of rules about when each thing should fire. It works until someone adds a second tab, or a second device, or a user who leaves the laptop open during lunch.

How sp00ky does it

You just subscribe to a query. The library handles everything that keeps it live.

  1. You call useQuery with your query. Your component gets the result.
  2. Behind the scenes, sp00ky opens one live channel to your database.
  3. When data changes, only the queries that care are updated.
  4. Your component re-renders with fresh data. You did not write any of this plumbing.
  5. When the component unmounts, the subscription cleans itself up.

Subscribe once. Everything that should change, changes. Everything that should not, doesn't.

Fresh everywhere, without a checklist

If your user has the app open in two tabs, a second device, or on a friend's laptop, every one of those screens stays in sync. You do not opt into this. It just works, because the same live channel feeds every client the same stream of changes.

  • Two tabs on the same laptop stay in sync.
  • Phone and desktop stay in sync.
  • Your teammate on the other side of the world stays in sync.
  • The coffee-shop tab you forgot about five hours ago catches up when you wake it.

Fast on purpose

The piece of sp00ky that routes changes to the right queries is written in Rust and runs in your browser as WebAssembly. It is small, it stays out of your way, and it only does work for queries that are actually affected by a change. Nothing else gets recomputed, nothing else wakes up, nothing else renders.

Proper benchmarks will follow in a later release, and we will update this page with numbers we trust enough to put our name on.

What you don't have to write anymore

  • Polling intervals. sp00ky is push-based, not "check every five seconds."
  • Manual cache invalidation after a mutation. The query that cared updates itself.
  • Refetch-on-focus logic. There is nothing to refetch when the data never went stale.
  • WebSocket boilerplate. One channel, opened for you, multiplexed across every subscription.
  • Cross-tab coordination. Other tabs get the same updates over the same channel.
  • Cleanup code. Subscriptions dispose themselves when your component goes away.

Ready to build something amazing?

Full docs, install guide, and API reference — all in one place.

Read the docs